Fix a couple Vale linter warnings

This commit is contained in:
Jeroen Leenarts
2022-12-06 15:41:05 +01:00
parent dbbb2f26be
commit a338b9b95f
67 changed files with 303 additions and 303 deletions
+15 -15
View File
@@ -1,4 +1,4 @@
Welcome to Streams Flutter repository! Thank you for taking the time to contribute to our codebase. 🎉. Welcome to Streams Flutter repository. Thank you for taking the time to contribute to our codebase. 🎉.
This document outlines a set of guidelines for contributing to Stream and our packages. These are mostly guidelines, not necessarily a fixed set of rules. Please use your best judgment and feel free to propose changes to this document in a pull request. This document outlines a set of guidelines for contributing to Stream and our packages. These are mostly guidelines, not necessarily a fixed set of rules. Please use your best judgment and feel free to propose changes to this document in a pull request.
@@ -26,7 +26,7 @@ Stream's Flutter code is kept in a single mono-repository consisting of multiple
### Project Structure 🧱 ### Project Structure 🧱
`.github` - GitHub files including issue templates, pull request templates, and Github Action scripts. `.github` - GitHub files including issue templates, pull request templates, and GitHub Action scripts.
`images` - Static images used in our README and elsewhere. `images` - Static images used in our README and elsewhere.
@@ -56,11 +56,11 @@ Stream's Flutter code is kept in a single mono-repository consisting of multiple
### Local Setup ### Local Setup
Congratulations! 🎉. You've successfully cloned our repo, and you are ready to make your first contribution. Before you can start making code changes, there are a few things to configure. Congratulations. 🎉. You've successfully cloned our repository, and you are ready to make your first contribution. Before you can start making code changes, there are a few things to configure.
**Melos Setup** **Melos Setup**
Stream uses `melos` to manage our mono-repository. For those unfamiliar, Melos is used to split up large code bases into separate independently versioned packages. To install melos, developers can run the following command: Stream uses `Melos` to manage our mono-repository. For those unfamiliar, Melos is used to split up large code bases into separate independently versioned packages. To install Melos, developers can run the following command:
```bash ```bash
pub global activate melos pub global activate melos
@@ -72,7 +72,7 @@ Once activated, users can now "bootstrap" their local clone by running the follo
melos bootstrap melos bootstrap
``` ```
Bootstrap will automatically fetch and link dependencies for all packages in the repo. It is the melos equivalent of running `flutter pub get`. Bootstrap will automatically fetch and link dependencies for all packages in the repository. It is the Melos equivalent of running `flutter pub get`.
Bonus Tip: Did you know it is possible to define and run custom scripts using Melos? Our team uses custom scripts for all sorts of actions like testing, lints, and more. Bonus Tip: Did you know it is possible to define and run custom scripts using Melos? Our team uses custom scripts for all sorts of actions like testing, lints, and more.
@@ -88,7 +88,7 @@ Are you ready to dive into code? It's pretty easy to get up and running with you
Before filing bugs, take a look at our existing backlog. For common bugs, there might be an existing ticket on GitHub. Before filing bugs, take a look at our existing backlog. For common bugs, there might be an existing ticket on GitHub.
To quickly narrow down the amount of tickets on Github, try filtering based on the label that best suites the bug. To quickly narrow down the amount of tickets on GitHub, try filtering based on the label that best suites the bug.
![image](https://user-images.githubusercontent.com/20601437/124240983-9d9f6100-db1b-11eb-952f-3c0cc60a910e.png) ![image](https://user-images.githubusercontent.com/20601437/124240983-9d9f6100-db1b-11eb-952f-3c0cc60a910e.png)
@@ -98,17 +98,17 @@ Didn't find an existing issue? Go ahead and file a new bug using one of our pre-
Be sure to provide as much information as possible when filing bug reports. A good issue should have steps to reproduce and information on your development environment and expected behavior. Be sure to provide as much information as possible when filing bug reports. A good issue should have steps to reproduce and information on your development environment and expected behavior.
Screenshots and gifs are always welcomed :) Screenshots and GIFs are always welcomed :)
## Feature Request 💡 ## Feature Request 💡
Have an idea for a new feature? We would love to hear about it! Have an idea for a new feature? We would love to hear about it.
Our team uses GitHub discussions to triage and discuss feature requests. Before opening a new topic, please check our existing issues and pull requests to ensure the feature you are suggesting is not already in progress. Our team uses GitHub discussions to triage and discuss feature requests. Before opening a new topic, please check our existing issues and pull requests to ensure the feature you are suggesting is not already in progress.
To file a feature request, select the "Discussions" tab on our GitHub repo or [visit this link](https://github.com/GetStream/stream-chat-flutter/discussions/new). Once there, change the default category to "**💡 Ideas**", then write a brief description of your feature/change. To file a feature request, select the "Discussions" tab on our GitHub repository or [visit this link](https://github.com/GetStream/stream-chat-flutter/discussions/new). Once there, change the default category to "**💡 Ideas**", then write a brief description of your feature/change.
Screenshots, sketches, and sample code are all welcomed! Screenshots, sketches, and sample code are all welcomed.
![image](https://user-images.githubusercontent.com/20601437/124241092-bc055c80-db1b-11eb-9205-7e3d7c157af1.png) ![image](https://user-images.githubusercontent.com/20601437/124241092-bc055c80-db1b-11eb-9205-7e3d7c157af1.png)
@@ -134,13 +134,13 @@ Add any other context or screenshots about the feature request here.
![image](https://user-images.githubusercontent.com/20601437/124241146-c7f11e80-db1b-11eb-9588-d9f578ec004a.png) ![image](https://user-images.githubusercontent.com/20601437/124241146-c7f11e80-db1b-11eb-9588-d9f578ec004a.png)
Thank you for taking the time to submit a patch and contribute to our codebase. You rock! Thank you for taking the time to submit a patch and contribute to our codebase. You rock.
Before we can land your pull request, please don't forget to [sign Stream's CLA (Contributor License Agreement](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform). 📝 Before we can land your pull request, please don't forget to [sign Stream's CLA (Contributor License Agreement](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform). 📝
### PR Semantics 🦄 ### PR Semantics 🦄
Our team uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) when coding and creating PRs. This standard makes it easy for our team to review and identify commits in our repo quickly. Our team uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) when coding and creating PRs. This standard makes it easy for our team to review and identify commits in our repository quickly.
While we don't expect developers to follow the specification down to every commit message, we enforce semantics on PR titles. While we don't expect developers to follow the specification down to every commit message, we enforce semantics on PR titles.
@@ -162,7 +162,7 @@ PR titles should follow the format below:
### Testing ### Testing
At Stream, we value testing. Every PR should include passing tests for existing and new features. To run our test suite locally, you can use the following *melos* command: At Stream, we value testing. Every PR should include passing tests for existing and new features. To run our test suite locally, you can use the following *Melos* command:
```bash ```bash
> melos run test:dart > melos run test:dart
@@ -173,13 +173,13 @@ At Stream, we value testing. Every PR should include passing tests for existing
By default, our development branch is `develop`. Contributors should create new PRs based on `develop` when working on new features. By default, our development branch is `develop`. Contributors should create new PRs based on `develop` when working on new features.
Develop is merged into master after the team performs various automated and QA tests on the branch. Master can be considered our stable branch it represents the latest published release on pub.dev. Develop is merged into master after the team performs various automated and QA tests on the branch. Master can be considered our stable branch, it represents the latest published release on pub.dev.
--- ---
# Versioning Policy # Versioning Policy
All of the Stream Chat packages follow [semantic versioning (semver)](https://semver.org/). All of the Stream Chat packages follow [semantic versioning](https://semver.org/).
See our [versioning policy documentation](https://getstream.io/chat/docs/sdk/flutter/basics/versioning_policy/) for more information. See our [versioning policy documentation](https://getstream.io/chat/docs/sdk/flutter/basics/versioning_policy/) for more information.
+8 -8
View File
@@ -3,7 +3,7 @@
![](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/images/sdk_hero_v4.png) ![](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/images/sdk_hero_v4.png)
![CI](https://github.com/GetStream/stream-chat-flutter/workflows/stream_flutter_workflow/badge.svg?branch=master) ![CI](https://github.com/GetStream/stream-chat-flutter/workflows/stream_flutter_workflow/badge.svg?branch=master)
[![melos](https://img.shields.io/badge/maintained%20with-melos-f700ff.svg?style=flat-square)](https://github.com/invertase/melos) [![Melos](https://img.shields.io/badge/maintained%20with-melos-f700ff.svg?style=flat-square)](https://github.com/invertase/melos)
**Quick Links** **Quick Links**
@@ -21,7 +21,7 @@ Stream allows developers to rapidly deploy scalable feeds and chat messaging wit
For upgrading from V3 to V4, please refer to the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migration_guide_4_0/) For upgrading from V3 to V4, please refer to the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migration_guide_4_0/)
## Sample apps and demos ## Sample apps and demos
Our team maintains a dedicated repository for fully-fledged sample applications and demos. Consider checking out [GetStream/flutter-samples](https://github.com/GetStream/flutter-samples) to learn more or get started by looking at our latest [Stream Chat demo](https://github.com/GetStream/flutter-samples/tree/main/packages/stream_chat_v1). Our team maintains a dedicated repository for full fledged sample applications and demos. Consider checking out [GetStream/flutter-samples](https://github.com/GetStream/flutter-samples) to learn more or get started by looking at our latest [Stream Chat demo](https://github.com/GetStream/flutter-samples/tree/main/packages/stream_chat_v1).
## Free for Makers ## Free for Makers
@@ -40,19 +40,19 @@ melos bootstrap
## Packages ## Packages
We provide a variety of packages depending on the level of customization you want to achieve. We provide a variety of packages depending on the level of customization you want to achieve.
### [stream_chat](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat) ### [`stream_chat`](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat)
A pure Dart package that can be used on any Dart project. It provides a low-level client to access the Stream Chat service. A pure Dart package that can be used on any Dart project. It provides a low-level client to access the Stream Chat service.
### [stream_chat_persistence](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_persistence) ### [`stream_chat_persistence`](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_persistence)
This package provides a persistence client for fetching and saving chat data locally. Stream Chat Persistence uses Moor as a disk cache. This package provides a persistence client for fetching and saving chat data locally. Stream Chat Persistence uses Moor as a disk cache.
### [stream_chat_flutter_core](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_flutter_core) ### [`stream_chat_flutter_core`](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_flutter_core)
This package provides business logic to fetch common things required for integrating Stream Chat into your application. The `core` package allows more customisation and hence provides business logic but no UI components. This package provides business logic to fetch common things required for integrating Stream Chat into your application. The `core` package allows more customisation and hence provides business logic but no UI components.
### [stream_chat_flutter](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_flutter) ### [`stream_chat_flutter`](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_flutter)
This library includes both a low-level chat SDK and a set of reusable and customizable UI components. This library includes both a low-level chat SDK and a set of reusable and customizable UI components.
### [stream_chat_localizations](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_localizations) ### [`stream_chat_localizations`](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_localizations)
This library includes a set of localization files for the Flutter UI components. This library includes a set of localization files for the Flutter UI components.
## Flutter Chat Tutorial ## Flutter Chat Tutorial
@@ -68,7 +68,7 @@ We also provide a set of sample apps created using the Stream Flutter SDK at [th
## Versioning Policy ## Versioning Policy
All of the Stream Chat packages follow [semantic versioning (semver)](https://semver.org/). All of the Stream Chat packages follow [semantic versioning](https://semver.org/).
See our [versioning policy documentation](https://getstream.io/chat/docs/sdk/flutter/basics/versioning_policy/) for more information. See our [versioning policy documentation](https://getstream.io/chat/docs/sdk/flutter/basics/versioning_policy/) for more information.
@@ -16,7 +16,7 @@ which allows you persist data locally which works with all packages.
### How do I choose? ### How do I choose?
#### The case for stream_chat_flutter #### The case for `stream_chat_flutter`
For the quickest way to integrate Stream Chat with your app, the UI SDK (`stream_chat_flutter`) is the For the quickest way to integrate Stream Chat with your app, the UI SDK (`stream_chat_flutter`) is the
way to go. `stream_chat_flutter` contains prebuilt components that manage most operations like data way to go. `stream_chat_flutter` contains prebuilt components that manage most operations like data
@@ -32,26 +32,26 @@ to request this through our support channels.
<b>Summary:</b> <b>Summary:</b>
For the quickest and easiest way to add Chat to your app with prebuilt UI components, use stream_chat_flutter For the quickest and easiest way to add Chat to your app with prebuilt UI components, use `stream_chat_flutter`
#### The case for stream_chat_flutter_core #### The case for `stream_chat_flutter_core`
If your application involves UI that does not fit in with the stream_chat_flutter components, stream_chat_flutter_core If your application involves UI that does not fit in with the `stream_chat_flutter` components, `stream_chat_flutter_core`
strips away the UI associated with the components and provides the data fetching and manipulation strips away the UI associated with the components and provides the data fetching and manipulation
capabilities while supplying builders for UI. This allows you to implement your own UI and themes capabilities while supplying builders for UI. This allows you to implement your own UI and themes
completely independently while not worrying about writing functions for data and pagination. completely independently while not worrying about writing functions for data and pagination.
<b>Summary:</b> <b>Summary:</b>
For implementing your own custom UI while not having to worry about lower level API calls, use stream_chat_flutter_core. For implementing your own custom UI while not having to worry about lower level API calls, use `stream_chat_flutter_core`.
#### The case for stream_chat #### The case for `stream_chat`
The stream_chat package is the Low-level Client (LLC) of Stream Chat in Flutter. This package wraps The `stream_chat` package is the Low-level Client (LLC) of Stream Chat in Flutter. This package wraps
the underlying functionality of Stream Chat and allows the most customization in terms of UI, data, the underlying functionality of Stream Chat and allows the most customization in terms of UI, data,
and architecture. and architecture.
<b>Summary:</b> <b>Summary:</b>
For the most control over the SDK and dealing with low level calls to the API, use stream_chat. For the most control over the SDK and dealing with low level calls to the API, use `stream_chat`.
@@ -20,18 +20,18 @@ giving you complete control to ones that give you a rich out-of-the-box chat exp
The packages that make up the Stream Chat SDK are: The packages that make up the Stream Chat SDK are:
1. <b>Low Level Client (stream_chat)</b>: a pure Dart package that can be used on any Dart project. 1. <b>Low Level Client (`stream_chat`)</b>: a pure Dart package that can be used on any Dart project.
It provides a low-level client to access the Stream Chat service. It provides a low-level client to access the Stream Chat service.
2. <b>Core (stream_chat_flutter_core)</b>: provides business logic to fetch common things required 2. <b>Core (`stream_chat_flutter_core`)</b>: provides business logic to fetch common things required
for integrating Stream Chat into your application. for integrating Stream Chat into your application.
The core package allows more customisation and hence provides business logic but no UI components. The core package allows more customisation and hence provides business logic but no UI components.
3. <b>UI (stream_chat_flutter)</b>: this library includes both a low-level chat SDK and a set of 3. <b>UI (`stream_chat_flutter`)</b>: this library includes both a low-level chat SDK and a set of
reusable and customisable UI components. reusable and customizable UI components.
4. <b>Persistence (stream_chat_persistence)</b>: provides a persistence client for fetching and 4. <b>Persistence (`stream_chat_persistence`)</b>: provides a persistence client for fetching and
saving chat data locally. saving chat data locally.
5. <b>Localizations (stream_chat_localizations)</b>: provides a set of localizations for the SDK. 5. <b>Localizations (`stream_chat_localizations`)</b>: provides a set of localizations for the SDK.
We recommend building prototypes using the full UI package, [stream_chat_flutter](https://pub.dev/packages/stream_chat_flutter), We recommend building prototypes using the full UI package, [`stream_chat_flutter`](https://pub.dev/packages/stream_chat_flutter),
since it contains UI widgets already integrated with Stream's API. It is the fastest way to get up since it contains UI widgets already integrated with Stream's API. It is the fastest way to get up
and running using Stream chat in your app. and running using Stream chat in your app.
@@ -39,7 +39,7 @@ The Flutter SDK enables you to build any type of chat or messaging experience fo
and Desktop. and Desktop.
If you're building a very custom UI and would prefer a more lean package, If you're building a very custom UI and would prefer a more lean package,
[stream_chat_flutter_core](https://pub.dev/packages/stream_chat_flutter_core) will be suited to this [`stream_chat_flutter_core`](https://pub.dev/packages/stream_chat_flutter_core) will be suited to this
use case. Core allows you to build custom, expressive UIs while retaining the benefits of our full use case. Core allows you to build custom, expressive UIs while retaining the benefits of our full
Flutter SDK. APIs for accessing and controlling users, sending messages, and so forth are seamlessly integrated Flutter SDK. APIs for accessing and controlling users, sending messages, and so forth are seamlessly integrated
into this package and accessible via providers and builders. into this package and accessible via providers and builders.
@@ -69,7 +69,7 @@ While this is a simplistic overview of the service, the Flutter SDK handles the
Before reading the docs, consider trying our [online API tour](https://getstream.io/chat/get_started/), Before reading the docs, consider trying our [online API tour](https://getstream.io/chat/get_started/),
it is a nice way to learn how the API works. it is a nice way to learn how the API works.
It's in-browser so you'll need to use Javascript but the core conceps are pretty much the same as Dart. It's in-browser so you'll need to use JavaScript but the core concepts are pretty much the same as Dart.
You may also like to look at the [Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) You may also like to look at the [Flutter tutorial](https://getstream.io/chat/flutter/tutorial/)
which focuses on using the UI package to get Stream Chat integrated into a Flutter app. which focuses on using the UI package to get Stream Chat integrated into a Flutter app.
@@ -4,7 +4,7 @@ sidebar_position: 3
title: Versioning Policy title: Versioning Policy
--- ---
All of the Stream Chat packages follow [semantic versioning (semver)](https://semver.org/). All of the Stream Chat packages follow [semantic versioning](https://semver.org/).
That means that with a version number x.y.z (major.minor.patch): That means that with a version number x.y.z (major.minor.patch):
- When releasing bug fixes (backwards compatible), we make a patch release by changing the z number (ex: 3.6.2 to 3.6.3). A bug fix is defined as an internal change that fixes incorrect behavior. - When releasing bug fixes (backwards compatible), we make a patch release by changing the z number (ex: 3.6.2 to 3.6.3). A bug fix is defined as an internal change that fixes incorrect behavior.
@@ -36,7 +36,7 @@ Additionally, pinning a message requires you to add the roles which are allowed
### Partially remove some message actions ### Partially remove some message actions
For example, if you only want to keep "copy message" and "delete message", For example, if you only want to keep "copy message" and "delete message":
here is how to do it using the `messageBuilder` with our `StreamMessageWidget`. here is how to do it using the `messageBuilder` with our `StreamMessageWidget`.
```dart ```dart
@@ -26,7 +26,7 @@ Let's build an example of location sharing option in the app:
![](../../assets/location_sharing_example.jpg) ![](../../assets/location_sharing_example.jpg)
* Show a "Share Location" button next to StreamMessageInput Textfield. * Show a "Share Location" button next to StreamMessageInput `Textfield`.
* When the user presses this button, it should fetch the current location coordinates of the user, and send a message on the channel as follows: * When the user presses this button, it should fetch the current location coordinates of the user, and send a message on the channel as follows:
@@ -46,7 +46,7 @@ Message(
) )
``` ```
For our example, we are going to use [geolocator](https://pub.dev/packages/geolocator) library. For our example, we are going to use [`geolocator`](https://pub.dev/packages/geolocator) library.
Please check their [setup instructions](https://pub.dev/packages/geolocator) on their docs. Please check their [setup instructions](https://pub.dev/packages/geolocator) on their docs.
NOTE: If you are testing on iOS simulator, you will need to set some dummy coordinates, as mentioned [here](https://stackoverflow.com/a/31238119/7489541). NOTE: If you are testing on iOS simulator, you will need to set some dummy coordinates, as mentioned [here](https://stackoverflow.com/a/31238119/7489541).
@@ -54,7 +54,7 @@ Also don't forget to enable "location update" capability in background mode, fro
On the receiver end, `location` type attachment should be rendered in map view, in the `StreamMessageListView`. On the receiver end, `location` type attachment should be rendered in map view, in the `StreamMessageListView`.
We are going to use [Google Static Maps API](https://developers.google.com/maps/documentation/maps-static/overview) to render the map in the message. We are going to use [Google Static Maps API](https://developers.google.com/maps/documentation/maps-static/overview) to render the map in the message.
You can use other libraries as well such as [google_maps_flutter](https://pub.dev/packages/google_maps_flutter). You can use other libraries as well such as [`google_maps_flutter`](https://pub.dev/packages/google_maps_flutter).
First, we add a button which when clicked fetches and shares location into the `MessageInput`: First, we add a button which when clicked fetches and shares location into the `MessageInput`:
@@ -19,7 +19,7 @@ This widget will be used to show the autocomplete options.
For this example we're using two external dependencies: For this example we're using two external dependencies:
- [emojis](https://pub.dev/packages/emojis) - [emojis](https://pub.dev/packages/emojis)
- [substring_highlight](https://pub.dev/packages/substring_highlight) - [`substring_highlight`](https://pub.dev/packages/substring_highlight)
```dart ```dart
import 'package:emojis/emoji.dart'; import 'package:emojis/emoji.dart';
@@ -38,7 +38,7 @@ In this example, you are doing a few important things in the ChannelListPage wid
- Using the **flutter_slidable** package to easily add slide functionality. - Using the **flutter_slidable** package to easily add slide functionality.
- Passing in the `itemBuilder` argument for the **StreamChannelListView** widget. This gives access to the current **BuildContext**, **Channel**, and **StreamChannelListTile**, and allows you to create, or customize, the stream channel list tiles. - Passing in the `itemBuilder` argument for the **StreamChannelListView** widget. This gives access to the current **BuildContext**, **Channel**, and **StreamChannelListTile**, and allows you to create, or customize, the stream channel list tiles.
- Returning a Slidable widget with two CustomSlidableAction widgets - to delete a channel and show more options. These widgets come from the flutter_slidable package. - Returning a Slidable widget with two CustomSlidableAction widgets - to delete a channel and show more options. These widgets come from the flutter_slidable package.
- Adding `onPressed` behaviour to call `showConfirmationBottomSheet` and `showChannelInfoModalBottomSheet`. These methods come from the **stream_chat_flutter** package. They have a few different on-tap callbacks you can supply, for example, `onViewInfoTap`. Alternatively, you can create custom dialogs from scratch. - Adding `onPressed` behaviour to call `showConfirmationBottomSheet` and `showChannelInfoModalBottomSheet`. These methods come from the **`stream_chat_flutter`** package. They have a few different on-tap callbacks you can supply, for example, `onViewInfoTap`. Alternatively, you can create custom dialog screens from scratch.
- Using the **StreamChannelListController** to perform actions, such as, `deleteChannel`. - Using the **StreamChannelListController** to perform actions, such as, `deleteChannel`.
```dart ```dart
@@ -39,16 +39,16 @@ This section provides setup instructions for the respective platforms.
#### Android #### Android
The package uses [photo_manager](https://pub.dev/packages/photo_manager) to access the device's photo library. Follow [this wiki](https://pub.dev/packages/photo_manager#android-10-q-29) to fulfill the Android requirements. The package uses [`photo_manager`](https://pub.dev/packages/photo_manager) to access the device's photo library. Follow [this wiki](https://pub.dev/packages/photo_manager#android-10-q-29) to fulfill the Android requirements.
#### iOS #### iOS
The library uses [flutter file picker plugin](https://github.com/miguelpruivo/flutter_file_picker) to pick The library uses [flutter file picker plugin](https://github.com/miguelpruivo/flutter_file_picker) to pick
files from the os. Follow [this wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#ios) to fulfill iOS requirements. files from the os. Follow [this wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#ios) to fulfill iOS requirements.
Stream Chat also uses the [video_player](https://pub.dev/packages/video_player) package to play videos. Follow [this guide](https://pub.dev/packages/video_player#installation) to fulfill the requirements. Stream Chat also uses the [`video_player`](https://pub.dev/packages/video_player) package to play videos. Follow [this guide](https://pub.dev/packages/video_player#installation) to fulfill the requirements.
Stream Chat uses the [image_picker](https://pub.dev/packages/image_picker) plugin. Stream Chat uses the [`image_picker`](https://pub.dev/packages/image_picker) plugin.
Follow [these instructions](https://pub.dev/packages/image_picker#ios) to check the requirements. Follow [these instructions](https://pub.dev/packages/image_picker#ios) to check the requirements.
#### Web #### Web
@@ -61,7 +61,7 @@ For the web, edit your `index.html` and add the following in the `<body>` tag to
#### macOS #### macOS
For macOS Stream Chat uses the [file_selector](https://pub.dev/packages/file_selector#macos) package. Follow [these instructions](https://pub.dev/packages/file_selector#macos) to check the requirements. For macOS Stream Chat uses the [`file_selector`](https://pub.dev/packages/file_selector#macos) package. Follow [these instructions](https://pub.dev/packages/file_selector#macos) to check the requirements.
You also need to add the following [entitlements](https://docs.flutter.dev/development/platform-integration/desktop#entitlements-and-the-app-sandbox) to `Release.entitlement` and `DebugProfile.entitlement`: You also need to add the following [entitlements](https://docs.flutter.dev/development/platform-integration/desktop#entitlements-and-the-app-sandbox) to `Release.entitlement` and `DebugProfile.entitlement`:
@@ -90,7 +90,7 @@ StreamChannelListHeader(
![](../assets/channel_list_header_custom_subtitle.png) ![](../assets/channel_list_header_custom_subtitle.png)
The `titleBuilder` param helps you build different titles depending on the connection state: The `titleBuilder` parameter helps you build different titles depending on the connection state:
```dart ```dart
//... //...
@@ -15,7 +15,7 @@ according to the filters and sort order given. However, in some cases, implement
that cannot be done using the customization approaches given in the widget. 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 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 fetches channels in the expected way via the usual parameters 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. exposes builders to build the UI in situations such as loading, empty data, errors, and on data received.
### Basic Example ### Basic Example
@@ -11,7 +11,7 @@ Find the pub.dev documentation [here](https://pub.dev/documentation/stream_chat_
`StreamChatCore` is used to provide information about the chat client to the widget tree. `StreamChatCore` is used to provide information about the chat client to the widget tree.
This Widget is used to react to life cycle changes and system updates. This Widget is used to react to life cycle changes and system updates.
When the app goes into the background, the websocket connection is automatically closed and when it goes back to foreground the connection is opened again. When the app goes into the background, the web socket connection is automatically closed and when it goes back to foreground the connection is opened again.
Like the `StreamChat` widget in the higher level UI package, the `StreamChatCore` widget should Like the `StreamChat` widget in the higher level UI package, the `StreamChatCore` widget should
be on the top level before using any Stream functionality: be on the top level before using any Stream functionality:
@@ -23,7 +23,7 @@ Filter.equal('type', 'messaging'),
#### Filter.notEqual #### Filter.notEqual
The 'notEqual' filter gets the objects where the given key does not have the specified value. The `notEqual` filter gets the objects where the given key does not have the specified value.
```dart ```dart
Filter.notEqual('type', 'messaging'), Filter.notEqual('type', 'messaging'),
@@ -63,20 +63,20 @@ Filter.lessOrEqual('count', 5),
#### Filter.in_ #### Filter.in_
The 'in_' filter allows getting objects where the key matches any in a specified array. The `in_` filter allows getting objects where the key matches any in a specified array.
```dart ```dart
Filter.in_('members', [user.id]) Filter.in_('members', [user.id])
``` ```
:::note :::note
Since 'in' is a keyword in Dart, the filter has an underscore added. This does not apply to the 'notIn' Since 'in' is a keyword in Dart, the filter has an underscore added. This does not apply to the `notIn`
keyword. keyword.
::: :::
#### Filter.notIn #### Filter.notIn
The 'notIn' filter allows getting objects where the key matches none in a specified array. The `notIn` filter allows getting objects where the key matches none in a specified array.
```dart ```dart
Filter.notIn('members', [user.id]) Filter.notIn('members', [user.id])
@@ -108,7 +108,7 @@ Filter.exists('name')
#### Filter.notExists #### Filter.notExists
The 'notExists' filter checks if the specified key doesn't exist. This is a simplified call to `Filter.exists` The `notExists` filter checks if the specified key doesn't exist. This is a simplified call to `Filter.exists`
with the value set to false. with the value set to false.
```dart ```dart
@@ -27,7 +27,7 @@ final client = StreamChatClient(
)..chatPersistenceClient = CustomChatPersistentClient(); )..chatPersistenceClient = CustomChatPersistentClient();
``` ```
We provide an official persistent client in the [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) We provide an official persistent client in the [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence)
package that works using the library [moor](https://moor.simonbinder.eu), an SQLite ORM. package that works using the library [moor](https://moor.simonbinder.eu), an SQLite ORM.
Add this to your package's `pubspec.yaml` file, using the latest version. Add this to your package's `pubspec.yaml` file, using the latest version.
@@ -154,7 +154,7 @@ Running the above will give this:
![](../assets/authentication_demo_app.jpg) ![](../assets/authentication_demo_app.jpg)
The `Auth` widget handles all of the authentication logic. It initializes a `FirebaseAuth.instance` and uses that The `Auth` widget handles all of the authentication logic. It initializes a `FirebaseAuth.instance` and uses that
in the `createAccount`, `signIn` and `signOut` methods. There is a button to envoke each of these methods. in the `createAccount`, `signIn` and `signOut` methods. There is a button to invoke each of these methods.
The `FirebaseFunctions.instance` will be used later in this guide. The `FirebaseFunctions.instance` will be used later in this guide.
@@ -288,7 +288,7 @@ firebase deploy --only functions
### Create a Stream User and Get the User's Token ### Create a Stream User and Get the User's Token
In the `createStreamUserAndGetToken` cloud function you create an `onCall` HTTPS handler, which exposes In the `createStreamUserAndGetToken` cloud function you create an `onCall` HTTPS handler, which exposes
a cloud function that can be envoked from your Flutter app. a cloud function that can be invoked from your Flutter app.
```js ```js
// Create a Stream user and return auth token. // Create a Stream user and return auth token.
@@ -324,13 +324,13 @@ by ensuring that `context.auth` is not null. If it is null, then it throws an `H
message. This error can be caught in your Flutter application. message. This error can be caught in your Flutter application.
If the caller is authenticated the function proceeds to use the `serverClient` to create a new Stream Chat If the caller is authenticated the function proceeds to use the `serverClient` to create a new Stream Chat
user by calling the `upsertUser` method and passing in some user data. It uses the authenticated caller's **uid** as an **id**. user by calling the `upsertUser` method and passing in some user data. It uses the authenticated caller's **`uid`** as an **id**.
After the user is created it generates a token for that user. This token is then returned to the caller. After the user is created it generates a token for that user. This token is then returned to the caller.
To call this from Flutter, you will need to use the `cloud_functions` package. To call this from Flutter, you will need to use the `cloud_functions` package.
Update the **createAccount** method in your Flutter code to the following: Update the **`createAccount`** method in your Flutter code to the following:
```dart ```dart
Future<void> createAccount() async { Future<void> createAccount() async {
@@ -354,7 +354,7 @@ in the request.
Once you have the Stream user token, you can authenticate your Stream Chat user as you normally would. Once you have the Stream user token, you can authenticate your Stream Chat user as you normally would.
Please see our [initialization documention](https://getstream.io/chat/docs/flutter-dart/init_and_users/?language=dart) for more information. Please see our [initialization documentation](https://getstream.io/chat/docs/flutter-dart/init_and_users/?language=dart) for more information.
As you can see below, the User ID matches on both Firebase's and Stream's user database. As you can see below, the User ID matches on both Firebase's and Stream's user database.
@@ -372,7 +372,7 @@ As you can see below, the User ID matches on both Firebase's and Stream's user d
The `getStreamUserToken` cloud function is very similar to the `createStreamUserAndGetToken` function. The only difference is The `getStreamUserToken` cloud function is very similar to the `createStreamUserAndGetToken` function. The only difference is
that it only creates a user token and does not create a new user account on Stream. that it only creates a user token and does not create a new user account on Stream.
Update the **signIn** method in your Flutter code to the following: Update the **`signIn`** method in your Flutter code to the following:
```dart ```dart
Future<void> signIn() async { Future<void> signIn() async {
@@ -433,7 +433,7 @@ exports.deleteStreamUser = functions.auth.user().onDelete((user, context) => {
``` ```
In this function, you are listening to delete events on Firebase auth. When an account is deleted, this function will be triggered, and you can get the In this function, you are listening to delete events on Firebase auth. When an account is deleted, this function will be triggered, and you can get the
user's **uid** and call the `deleteUser` method on the `serverClient`. user's **`uid`** and call the `deleteUser` method on the `serverClient`.
This is not an external cloud function; it can only be triggered when an This is not an external cloud function; it can only be triggered when an
account is deleted. account is deleted.
@@ -21,7 +21,7 @@ Make sure to check [this section](https://getstream.io/chat/docs/flutter-dart/pu
### Setup FCM ### Setup FCM
To integrate push notifications in your Flutter app you need to use the package [firebase_messaging](https://pub.dev/packages/firebase_messaging). To integrate push notifications in your Flutter app you need to use the package [`firebase_messaging`](https://pub.dev/packages/firebase_messaging).
Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to know how to set up the plugin for both Android and iOS. Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to know how to set up the plugin for both Android and iOS.
@@ -61,7 +61,7 @@ Upload the `Server Key` in your chat dashboard
:::note :::note
We are setting up the Android section, but this will work for both Android and iOS if you're using Firebase for both of them! We are setting up the Android section, but this will work for both Android and iOS if you're using Firebase for both of them.
::: :::
#### Step 6 #### Step 6
@@ -97,21 +97,21 @@ firebaseMessaging.onTokenRefresh.listen((token) {
### Possible issues ### Possible issues
We only send push notifications when the user doesn't have any active websocket connection (which is established when you call `client.connectUser`). If you set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) property of the StreamChat widget, when your app goes to background, your device will keep the ws connection alive for 1 minute, and so within this period, you won't receive any push notification. We only send push notifications when the user doesn't have any active web socket connection (which is established when you call `client.connectUser`). If you set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) property of the StreamChat widget, when your app goes to background, your device will keep the WS connection alive for 1 minute, and so within this period, you won't receive any push notification.
Make sure to read the [general push docs](https://getstream.io/chat/docs/flutter-dart/push_introduction/?language=dart) in order to avoid known gotchas that may make your relationship with notifications go bad 😢 Make sure to read the [general push docs](https://getstream.io/chat/docs/flutter-dart/push_introduction/?language=dart) in order to avoid known gotchas that may make your relationship with notifications go bad 😢
### Testing if Push Notifications are Setup Correctly ### Testing if Push Notifications are Setup Correctly
If you're not sure if you've set up push notifications correctly (e.g. you don't always receive them, they work unreliably), you can follow these steps to make sure your config is correct and working: If you're not sure if you've set up push notifications correctly (for example you don't always receive them, they work unreliably), you can follow these steps to make sure your configuration is correct and working:
1. Clone our repo for push testing git clone git@github.com:GetStream/chat-push-test.git 1. Clone our repository for push testing git clone git@github.com:GetStream/chat-push-test.git
2. `cd flutter` 2. `cd flutter`
3. In folder run `flutter pub get` 3. In folder run `flutter pub get`
4. Input your api key and secret in `lib/main.dart` 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 in your device (**do not** run on iOS simulator, Android emulator is fine) 5. Change the bundle identifier/application ID and development team/user so you can run the app in your device (**do not** run on iOS simulator, Android emulator is fine)
@@ -137,11 +137,11 @@ You should get a test push notification
The [StreamChat](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat-class.html) widget lets you define a [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) handler in order to handle events while the app is in the background, but the client is still connected. The [StreamChat](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat-class.html) widget lets you define a [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) handler in order to handle events while the app is in the background, but the client is still connected.
This is useful because it lets you keep the connection alive in cases in which the app goes in the background just for some seconds (eg: multitasking, picking pictures from the gallery...) This is useful because it lets you keep the connection alive in cases in which the app goes in the background just for some seconds (for example multitasking, picking pictures from the gallery...)
You can even customize the [backgroundKeepAlive](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/backgroundKeepAlive.html) duration. You can even customize the [backgroundKeepAlive](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/backgroundKeepAlive.html) duration.
In order to show notifications in such a case we suggest using the package [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications); follow the package guide to successfully set up the plugin. In order to show notifications in such a case we suggest using the package [`flutter_local_notifications`](https://pub.dev/packages/flutter_local_notifications); follow the package guide to successfully set up the plugin.
Once that's done you should set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html); here is an example: Once that's done you should set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html); here is an example:
@@ -234,7 +234,7 @@ To do this we need to update the push notification data payload at Stream Dashbo
} }
``` ```
Then we need to integrate the package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, learn [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up. Then we need to integrate the package [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, learn [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up.
Then during the call `firebaseMessaging.configure(...)` we need to set the `onBackgroundMessage` parameter using a TOP-LEVEL or STATIC function to handle background messages; here is an example: Then during the call `firebaseMessaging.configure(...)` we need to set the `onBackgroundMessage` parameter using a TOP-LEVEL or STATIC function to handle background messages; here is an example:
@@ -17,7 +17,7 @@ You can read more about Streams [push delivery logic](https://getstream.io/ch
### Setup FCM ### Setup FCM
To integrate push notifications in your Flutter app, you need to use the package [firebase_messaging](https://pub.dev/packages/firebase_messaging). To integrate push notifications in your Flutter app, you need to use the package [`firebase_messaging`](https://pub.dev/packages/firebase_messaging).
Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to set up the plugin for Android and iOS. Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to set up the plugin for Android and iOS.
@@ -55,7 +55,7 @@ You can upload your Firebase credentials using either the dashboard or the app s
![](../../assets/firebase_notifications_toggle-5aeabfcbdc24cb8f1fea7d41d0e845fc.png) ![](../../assets/firebase_notifications_toggle-5aeabfcbdc24cb8f1fea7d41d0e845fc.png)
3. Enter your Firebase Credentials and press "Save". 3. Enter your Firebase Credentials and press `"Save"`.
##### Using the API ##### Using the API
@@ -86,7 +86,7 @@ firebaseMessaging.onTokenRefresh.listen((token) {
}); });
``` ```
Push Notifications v2 also supports specifying a name to the push device tokens you register. By setting the optional `pushProviderName` param in the `addDevice` call you can support different configurations between the device and the `PushProvider`. Push Notifications v2 also supports specifying a name to the push device tokens you register. By setting the optional `pushProviderName` parameter in the `addDevice` call you can support different configurations between the device and the `PushProvider`.
```dart ```dart
firebaseMessaging.onTokenRefresh.listen((token) { firebaseMessaging.onTokenRefresh.listen((token) {
@@ -105,7 +105,7 @@ On iOS we send both a **notification** and a **data** payload.
This means you don't need to do anything special to get the notification to show up. However, you might want to handle the data payload to perform some logic when the user taps on the notification. This means you don't need to do anything special to get the notification to show up. However, you might want to handle the data payload to perform some logic when the user taps on the notification.
To update the template, you can use a backend SDK. To update the template, you can use a backend SDK.
For example, using the javascript SDK: For example, using the JavaScript SDK:
```js ```js
const client = StreamChat.getInstance(api_key, api_secret); const client = StreamChat.getInstance(api_key, api_secret);
@@ -181,13 +181,13 @@ void handleNotification(
FirebaseMessaging.onBackgroundMessage(onBackgroundMessage); FirebaseMessaging.onBackgroundMessage(onBackgroundMessage);
``` ```
In the above example, you get the message details using the `getMessage` method and then you use the [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications) package to show the actual notification. In the above example, you get the message details using the `getMessage` method and then you use the [`flutter_local_notifications`](https://pub.dev/packages/flutter_local_notifications) package to show the actual notification.
##### Using a Template on Android ##### Using a Template on Android
It's still possible to add a **notification** payload to Android notifications. It's still possible to add a **notification** payload to Android notifications.
You can do so by adding a template using a backend SDK. You can do so by adding a template using a backend SDK.
For example, using the javascript SDK: For example, using the JavaScript SDK:
```js ```js
const client = StreamChat.getInstance(api_key, api_secret); const client = StreamChat.getInstance(api_key, api_secret);
@@ -211,11 +211,11 @@ Make sure to read the [general push notification docs](https://getstream.io/chat
### Testing if Push Notifications are Setup Correctly ### Testing if Push Notifications are Setup Correctly
If you're not sure whether you've set up push notifications correctly, for example, you don't always receive them, or they dont work reliably, then you can follow these steps to make sure your config is correct and working: If you're not sure whether you've set up push notifications correctly, for example, you don't always receive them, or they dont work reliably, then you can follow these steps to make sure your configuration is correct and working:
1. Clone our repo for push testing: `git clone git@github.com:GetStream/chat-push-test.git` 1. Clone our repository for push testing: `git clone git@github.com:GetStream/chat-push-test.git`
2. `cd flutter` 2. `cd flutter`
3. In that folder run `flutter pub get` 3. In that folder run `flutter pub get`
4. Input your api key and secret in `lib/main.dart` 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. 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.
6. Add your `google-services.json/GoogleService-Info.plist` 6. Add your `google-services.json/GoogleService-Info.plist`
7. Run the app 7. Run the app
@@ -257,7 +257,7 @@ Take a look at the [Stream Chat v1 sample app](https://github.com/GetStream/flut
When the app is closed you may want to save received messages when you receive them via a notification so that later on when you open the app they're already there. When the app is closed you may want to save received messages when you receive them via a notification so that later on when you open the app they're already there.
To do this you need to integrate the package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, see [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up. To do this you need to integrate the package [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, see [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up.
Then calling `FirebaseMessaging.onBackgroundMessage(...)` you need to use a TOP-LEVEL or STATIC function to handle background messages; here is an example: Then calling `FirebaseMessaging.onBackgroundMessage(...)` you need to use a TOP-LEVEL or STATIC function to handle background messages; here is an example:
@@ -37,7 +37,7 @@ Check out the diagram below for an example:
### Dependencies ### Dependencies
Add the [webcrypto](https://pub.dev/packages/webcrypto) package in your `pubspec.yaml` file. Add the [`webcrypto`](https://pub.dev/packages/webcrypto) package in your `pubspec.yaml` file.
```yaml ```yaml
dependencies: dependencies:
@@ -77,9 +77,9 @@ class JsonWebKeyPair {
} }
``` ```
### Generate a Crypto Key ### Generate a Cryptographic Key
Next, create a symmetric **Crypto Key** using the keys generated in the previous step. Next, create a symmetric **Cryptographic Key** using the keys generated in the previous step.
You will use those keys to encrypt and decrypt messages. You will use those keys to encrypt and decrypt messages.
```dart ```dart
@@ -108,7 +108,7 @@ Future<List<int>> deriveKey(String senderJwk, String receiverJwk) async {
### Encrypting Messages ### Encrypting Messages
Once you have generated the **Crypto Key**, you're ready to encrypt the message. Once you have generated the **Cryptographic Key**, you're ready to encrypt the message.
You can use the **AES-GCM** algorithm for its known security and performance balance and good browser availability. You can use the **AES-GCM** algorithm for its known security and performance balance and good browser availability.
```dart ```dart
@@ -254,6 +254,6 @@ StreamMessageListView(
), ),
``` ```
That's it! That's all you need to implement E2EE in a Stream powered chat app. That's it. That's all you need to implement E2EE in a Stream powered chat app.
For more details, check out our [end-to-end encrypted chat article](https://getstream.io/blog/end-to-end-encrypted-chat-in-flutter/#whats-end-to-end-encryption). For more details, check out our [end-to-end encrypted chat article](https://getstream.io/blog/end-to-end-encrypted-chat-in-flutter/#whats-end-to-end-encryption).
@@ -14,7 +14,7 @@ If you find any bugs or have any questions, please file an [issue on our GitHub
Code examples: Code examples:
- See our [Stream Chat Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) for an up-to-date guide using the latest Stream Chat version. - See our [Stream Chat Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) for an up-to-date guide using the latest Stream Chat version.
- See the [Stream Flutter Samples repository](https://github.com/GetStream/flutter-samples) with our fully-fledged messaging [sample application](https://github.com/GetStream/flutter-samples/tree/main/packages/stream_chat_v1). - See the [Stream Flutter Samples repository](https://github.com/GetStream/flutter-samples) with our full fledged messaging [sample application](https://github.com/GetStream/flutter-samples/tree/main/packages/stream_chat_v1).
All of our documentation has also been updated to support v4, so all of the guides and examples will have updated code. All of our documentation has also been updated to support v4, so all of the guides and examples will have updated code.
@@ -209,10 +209,10 @@ Let's explore some examples of the functional differences when using the new `St
The **StreamChannelListController** provides various methods, such as: The **StreamChannelListController** provides various methods, such as:
- **deleteChannel** - **`deleteChannel`**
- **loadMore** - **`loadMore`**
- **muteChannel** - **`muteChannel`**
- **deleteChannel** - **`deleteChannel`**
For a complete list with additional information, see the code documentation. For a complete list with additional information, see the code documentation.
@@ -537,7 +537,7 @@ Creating a separate controller allows easier control over the message input cont
The widget is also separated into smaller components: `StreamCountDownButton`, `StreamAttachmentPicker`, etc. The widget is also separated into smaller components: `StreamCountDownButton`, `StreamAttachmentPicker`, etc.
> ❗The `MessageInputController` is exposed by the **stream_chat_flutter_core** package. This allows you to use the controller even if you're not using the UI components. > ❗The `MessageInputController` is exposed by the **`stream_chat_flutter_core`** package. This allows you to use the controller even if you're not using the UI components.
As a result of this extra control, it is no longer needed for the new `StreamMessageInput` widget to expose these `MessageInput` arguments: As a result of this extra control, it is no longer needed for the new `StreamMessageInput` widget to expose these `MessageInput` arguments:
@@ -734,7 +734,7 @@ The controller makes it much simpler to dynamically modify the message input.
## Stream Chat Flutter Core ## Stream Chat Flutter Core
Various changes have been made to the Core package, most notably, the indroduction of all of the controllers mentioned above. Various changes have been made to the Core package, most notably, the introduction of all of the controllers mentioned above.
These controllers replace the business logic implementations (Bloc). Please note that this is not related to the well-known Flutter Bloc package, but instead refers to the naming we used for our business logic components. These controllers replace the business logic implementations (Bloc). Please note that this is not related to the well-known Flutter Bloc package, but instead refers to the naming we used for our business logic components.
@@ -16,7 +16,7 @@ If you find any bugs or have any questions, please file an [issue on our GitHub
Code examples: Code examples:
- See our [Stream Chat Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) for an up-to-date guide using the latest Stream Chat version. - See our [Stream Chat Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) for an up-to-date guide using the latest Stream Chat version.
- See the [Stream Flutter Samples repository](https://github.com/GetStream/flutter-samples) with our fully-fledged messaging [sample application](https://github.com/GetStream/flutter-samples/tree/main/packages/stream_chat_v1). - See the [Stream Flutter Samples repository](https://github.com/GetStream/flutter-samples) with our full fledged messaging [sample application](https://github.com/GetStream/flutter-samples/tree/main/packages/stream_chat_v1).
Our documentation has also been updated to support v5, so all guides and examples will have updated code. Our documentation has also been updated to support v5, so all guides and examples will have updated code.
@@ -59,7 +59,7 @@ The user experience of interacting with a desktop application differs from a mob
- Input controls: touch, keyboard, and mouse interactions - Input controls: touch, keyboard, and mouse interactions
- Native file system or gallery access (as well as sharing functionality) - Native file system or gallery access (as well as sharing functionality)
- Shortcuts - Shortcuts
- Dialogs - Dialog screens
By default, Stream Chat Flutter will use the correct input controls and visual elements for the target platform. For example, touch and swipe controls will be the default on mobile, while on web and desktop these will be disabled and interactions with the mouse and keyboard will be preferred. By default, Stream Chat Flutter will use the correct input controls and visual elements for the target platform. For example, touch and swipe controls will be the default on mobile, while on web and desktop these will be disabled and interactions with the mouse and keyboard will be preferred.
@@ -70,7 +70,7 @@ On desktop and web it's also possible to add attachments by simply dragging them
- Right-click context menus for messages and full-screen attachments. - Right-click context menus for messages and full-screen attachments.
- Upload and download attachments using the native desktop file system. - Upload and download attachments using the native desktop file system.
- Press the "enter" key to send a message. - Press the "enter" key to send a message.
- If you are quoting a message and have not yet typed any text, you can press the "esc" key to remove the quoted message. - If you are quoting a message and have not yet typed any text, you can press the `"esc"` key to remove the quoted message.
- A dedicated "X" button for removing a quoted message with your mouse. - A dedicated "X" button for removing a quoted message with your mouse.
- Drag and drop attachment files to `StreamMessageInput`. - Drag and drop attachment files to `StreamMessageInput`.
- New `StreamMessageInput.draggingBorder` property to customize the border color of the message input when dropping a file. - New `StreamMessageInput.draggingBorder` property to customize the border color of the message input when dropping a file.
@@ -81,10 +81,10 @@ On desktop and web it's also possible to add attachments by simply dragging them
- Gallery navigation controls with keyboard shortcuts (left and right arrow keys). - Gallery navigation controls with keyboard shortcuts (left and right arrow keys).
- Appropriate message sizing for large screens. - Appropriate message sizing for large screens.
- Right-click context menu for `StreamMessageListView` items. - Right-click context menu for `StreamMessageListView` items.
- `StreamMessageListView` items not swipeable on desktop & web. - `StreamMessageListView` items not swipe-able on desktop & web.
- Video support for Windows & Linux through `dart_vlc`. - Video support for Windows & Linux through `dart_vlc`.
- Video support for macOS through `video_player_macos`. - Video support for macOS through `video_player_macos`.
- Replace bottom sheets with dialogs where appropriate. - Replace bottom sheets with dialog screens where appropriate.
## What's New? ## What's New?
@@ -118,7 +118,7 @@ Check out the dedicated [guide](../../02-customization/01-custom-widgets/05-cust
The following was also introduced: The following was also introduced:
- Added support for additional text field params in`StreamMessageInput`: `maxLines`, `minLines`, `textInputAction`, `keyboardType`, and `textCapitalization`. - Added support for additional text field parameters in`StreamMessageInput`: `maxLines`, `minLines`, `textInputAction`, `keyboardType`, and `textCapitalization`.
- Added `showStreamAttachmentPickerModalBottomSheet` to show the attachment picker modal bottom sheet. - Added `showStreamAttachmentPickerModalBottomSheet` to show the attachment picker modal bottom sheet.
- Added `onQuotedMessageCleared` to `StreamMessageInput` - Added `onQuotedMessageCleared` to `StreamMessageInput`
- `selected` and `selectedTileColor` to `StreamChannelListTile` - `selected` and `selectedTileColor` to `StreamChannelListTile`
@@ -196,7 +196,7 @@ Both of these will ensure the route is disposed of and the user is disconnected
Another approach would be to introduce a new [Navigator](https://api.flutter.dev/flutter/widgets/Navigator-class.html). Another approach would be to introduce a new [Navigator](https://api.flutter.dev/flutter/widgets/Navigator-class.html).
This has the benefit that everything related to Stream chat is contained to a specific part of the widget tree. This has the benefit that everything related to Stream chat is contained to a specific part of the widget tree.
### Defining Routes and Subroutes ### Defining Routes and Nested Routes
In this example, our application has the following routes. In this example, our application has the following routes.
@@ -208,7 +208,7 @@ const routeChatChannels = 'chat_channels';
const routeChatChannel = 'chat_channel'; const routeChatChannel = 'chat_channel';
``` ```
For the `/chat/` subroutes (**routePrefixChat**), this approach initializes Stream Chat in our application and introduces a nested navigator. For the `/chat/` nested routes (**routePrefixChat**), this approach initializes Stream Chat in our application and introduces a nested navigator.
Lets explore the code: Lets explore the code:
@@ -267,7 +267,7 @@ In the above code youre:
1. Creating a navigator key, passing it to `MaterialApp`, and exposing it to the whole application using Provider (you can expose it however you want). 1. Creating a navigator key, passing it to `MaterialApp`, and exposing it to the whole application using Provider (you can expose it however you want).
2. Creating `onGenerateRoute` that specifies what page to show depending on the route. Most importantly, if the route contains the **routePrefixChat,** it navigates to the **ChatSetup** page and passes in the remainder of the route. 2. Creating `onGenerateRoute` that specifies what page to show depending on the route. Most importantly, if the route contains the **routePrefixChat,** it navigates to the **ChatSetup** page and passes in the remainder of the route.
For example, `Navigator.pushNamed(context, routeChatHome)` will navigate to the **ChatSetup** page and pass in the subroute **routeChatChannels.** For example, `Navigator.pushNamed(context, routeChatHome)` will navigate to the **ChatSetup** page and pass in the nested route **routeChatChannels.**
### Stream Chat Initialization, User Connection, and Nested Navigation ### Stream Chat Initialization, User Connection, and Nested Navigation
@@ -456,7 +456,7 @@ This final example will be a combination of the first two options. The following
### Application Routes and Conditional Stream Initialization ### Application Routes and Conditional Stream Initialization
For this example we have the following routes and subroutes: For this example we have the following routes and nested routes:
```dart ```dart
|_ '/' -> home page |_ '/' -> home page
@@ -553,7 +553,7 @@ If youre unfamiliar with GoRouter it will help to first read the documentatio
There are a few important things to note in the above code: There are a few important things to note in the above code:
- Define our routes and subroutes - Define our routes and nested routes
- Specify the initial route with `initialLocation` - Specify the initial route with `initialLocation`
- Use the `navigatorBuilder` to wrap certain routes with **StreamChat** and **ChatSetup**. - Use the `navigatorBuilder` to wrap certain routes with **StreamChat** and **ChatSetup**.
- The `wasPreviousRouteChat` \***\*boolean is used to determine if the previous route was a chat route. This is important because when you press the back button from the `/chat` route and navigate to the `/` route, the **StreamChat** widget still needs to be accessible while the navigation transition occurs. However, if you then navigate to the `/setting` route, you no longer need the **StreamChat\*\* widget and can safely remove it. - The `wasPreviousRouteChat` \***\*boolean is used to determine if the previous route was a chat route. This is important because when you press the back button from the `/chat` route and navigate to the `/` route, the **StreamChat** widget still needs to be accessible while the navigation transition occurs. However, if you then navigate to the `/setting` route, you no longer need the **StreamChat\*\* widget and can safely remove it.
@@ -14,7 +14,7 @@ which allows you persist data locally which works with all packages.
### How do I choose? ### How do I choose?
#### The case for stream_chat_flutter #### The case for `stream_chat_flutter`
For the quickest way to integrate Stream Chat with your app, the UI SDK (`stream_chat_flutter`) is the For the quickest way to integrate Stream Chat with your app, the UI SDK (`stream_chat_flutter`) is the
way to go. `stream_chat_flutter` contains prebuilt components that manage most operations like data way to go. `stream_chat_flutter` contains prebuilt components that manage most operations like data
@@ -30,26 +30,26 @@ to request this through our support channels.
<b>Summary:</b> <b>Summary:</b>
For the quickest and easiest way to add Chat to your app with prebuilt UI components, use stream_chat_flutter For the quickest and easiest way to add Chat to your app with prebuilt UI components, use `stream_chat_flutter`
#### The case for stream_chat_flutter_core #### The case for `stream_chat_flutter_core`
If your application involves UI that does not fit in with the stream_chat_flutter components, stream_chat_flutter_core If your application involves UI that does not fit in with the `stream_chat_flutter` components, `stream_chat_flutter_core`
strips away the UI associated with the components and provides the data fetching and manipulation strips away the UI associated with the components and provides the data fetching and manipulation
capabilities while supplying builders for UI. This allows you to implement your own UI and themes capabilities while supplying builders for UI. This allows you to implement your own UI and themes
completely independently while not worrying about writing functions for data and pagination. completely independently while not worrying about writing functions for data and pagination.
<b>Summary:</b> <b>Summary:</b>
For implementing your own custom UI while not having to worry about lower level API calls, use stream_chat_flutter_core. For implementing your own custom UI while not having to worry about lower level API calls, use `stream_chat_flutter_core`.
#### The case for stream_chat #### The case for `stream_chat`
The stream_chat package is the Low-level Client (LLC) of Stream Chat in Flutter. This package wraps The `stream_chat` package is the Low-level Client (LLC) of Stream Chat in Flutter. This package wraps
the underlying functionality of Stream Chat and allows the most customization in terms of UI, data, the underlying functionality of Stream Chat and allows the most customization in terms of UI, data,
and architecture. and architecture.
<b>Summary:</b> <b>Summary:</b>
For the most control over the SDK and dealing with low level calls to the API, use stream_chat. For the most control over the SDK and dealing with low level calls to the API, use `stream_chat`.
@@ -20,18 +20,18 @@ giving you complete control to ones that give you a rich out-of-the-box chat exp
The packages that make up the Stream Chat SDK are: The packages that make up the Stream Chat SDK are:
1. <b>Low Level Client (stream_chat)</b>: a pure Dart package that can be used on any Dart project. 1. <b>Low Level Client (`stream_chat`)</b>: a pure Dart package that can be used on any Dart project.
It provides a low-level client to access the Stream Chat service. It provides a low-level client to access the Stream Chat service.
2. <b>Core (stream_chat_flutter_core)</b>: provides business logic to fetch common things required 2. <b>Core (`stream_chat_flutter_core`)</b>: provides business logic to fetch common things required
for integrating Stream Chat into your application. for integrating Stream Chat into your application.
The core package allows more customisation and hence provides business logic but no UI components. The core package allows more customisation and hence provides business logic but no UI components.
3. <b>UI (stream_chat_flutter)</b>: this library includes both a low-level chat SDK and a set of 3. <b>UI (`stream_chat_flutter`)</b>: this library includes both a low-level chat SDK and a set of
reusable and customisable UI components. reusable and customizable UI components.
4. <b>Persistence (stream_chat_persistence)</b>: provides a persistence client for fetching and 4. <b>Persistence (`stream_chat_persistence`)</b>: provides a persistence client for fetching and
saving chat data locally. saving chat data locally.
5. <b>Localizations (stream_chat_localizations)</b>: provides a set of localizations for the SDK. 5. <b>Localizations (`stream_chat_localizations`)</b>: provides a set of localizations for the SDK.
We recommend building prototypes using the full UI package, [stream_chat_flutter](https://pub.dev/packages/stream_chat_flutter), We recommend building prototypes using the full UI package, [`stream_chat_flutter`](https://pub.dev/packages/stream_chat_flutter),
since it contains UI widgets already integrated with Stream's API. It is the fastest way to get up since it contains UI widgets already integrated with Stream's API. It is the fastest way to get up
and running using Stream chat in your app. and running using Stream chat in your app.
@@ -39,7 +39,7 @@ The Flutter SDK enables you to build any type of chat or messaging experience fo
and Desktop. and Desktop.
If you're building a very custom UI and would prefer a more lean package, If you're building a very custom UI and would prefer a more lean package,
[stream_chat_flutter_core](https://pub.dev/packages/stream_chat_flutter_core) will be suited to this [`stream_chat_flutter_core`](https://pub.dev/packages/stream_chat_flutter_core) will be suited to this
use case. Core allows you to build custom, expressive UIs while retaining the benefits of our full use case. Core allows you to build custom, expressive UIs while retaining the benefits of our full
Flutter SDK. APIs for accessing and controlling users, sending messages, and so forth are seamlessly integrated Flutter SDK. APIs for accessing and controlling users, sending messages, and so forth are seamlessly integrated
into this package and accessible via providers and builders. into this package and accessible via providers and builders.
@@ -69,7 +69,7 @@ While this is a simplistic overview of the service, the Flutter SDK handles the
Before reading the docs, consider trying our [online API tour](https://getstream.io/chat/get_started/), Before reading the docs, consider trying our [online API tour](https://getstream.io/chat/get_started/),
it is a nice way to learn how the API works. it is a nice way to learn how the API works.
It's in-browser so you'll need to use Javascript but the core conceps are pretty much the same as Dart. It's in-browser so you'll need to use JavaScript but the core concepts are pretty much the same as Dart.
You may also like to look at the [Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) You may also like to look at the [Flutter tutorial](https://getstream.io/chat/flutter/tutorial/)
which focuses on using the UI package to get Stream Chat integrated into a Flutter app. which focuses on using the UI package to get Stream Chat integrated into a Flutter app.
@@ -4,7 +4,7 @@ sidebar_position: 3
title: Versioning Policy title: Versioning Policy
--- ---
All of the Stream Chat packages follow [semantic versioning (semver)](https://semver.org/). All of the Stream Chat packages follow [semantic versioning](https://semver.org/).
That means that with a version number x.y.z (major.minor.patch): That means that with a version number x.y.z (major.minor.patch):
- When releasing bug fixes (backwards compatible), we make a patch release by changing the z number (ex: 3.6.2 to 3.6.3). A bug fix is defined as an internal change that fixes incorrect behavior. - When releasing bug fixes (backwards compatible), we make a patch release by changing the z number (ex: 3.6.2 to 3.6.3). A bug fix is defined as an internal change that fixes incorrect behavior.
@@ -27,7 +27,7 @@ Let's build an example of location sharing option in the app:
![](../assets/location_sharing_example.jpg) ![](../assets/location_sharing_example.jpg)
* Show a "Share Location" button next to MessageInput Textfield. * Show a "Share Location" button next to MessageInput `Textfield`.
* When the user presses this button, it should fetch the current location coordinates of the user, and send a message on the channel as follows: * When the user presses this button, it should fetch the current location coordinates of the user, and send a message on the channel as follows:
@@ -47,7 +47,7 @@ Message(
) )
``` ```
For our example, we are going to use [geolocator](https://pub.dev/packages/geolocator) library. For our example, we are going to use [`geolocator`](https://pub.dev/packages/geolocator) library.
Please check their [setup instructions](https://pub.dev/packages/geolocator) on their docs. Please check their [setup instructions](https://pub.dev/packages/geolocator) on their docs.
NOTE: If you are testing on iOS simulator, you will need to set some dummy coordinates, as mentioned [here](https://stackoverflow.com/a/31238119/7489541). NOTE: If you are testing on iOS simulator, you will need to set some dummy coordinates, as mentioned [here](https://stackoverflow.com/a/31238119/7489541).
@@ -55,7 +55,7 @@ Also don't forget to enable "location update" capability in background mode, fro
On the receiver end, `location` type attachment should be rendered in map view, in the `MessageListView`. On the receiver end, `location` type attachment should be rendered in map view, in the `MessageListView`.
We are going to use [Google Static Maps API](https://developers.google.com/maps/documentation/maps-static/overview) to render the map in the message. We are going to use [Google Static Maps API](https://developers.google.com/maps/documentation/maps-static/overview) to render the map in the message.
You can use other libraries as well such as [google_maps_flutter](https://pub.dev/packages/google_maps_flutter). You can use other libraries as well such as [`google_maps_flutter`](https://pub.dev/packages/google_maps_flutter).
First, we add a button which when clicked fetches and shares location into the `MessageInput`: First, we add a button which when clicked fetches and shares location into the `MessageInput`:
@@ -28,7 +28,7 @@ final client = StreamChatClient(
)..chatPersistenceClient = CustomChatPersistentClient(); )..chatPersistenceClient = CustomChatPersistentClient();
``` ```
We provide an official persistent client in the [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) We provide an official persistent client in the [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence)
package that works using the library [moor](https://moor.simonbinder.eu), an SQLite ORM. package that works using the library [moor](https://moor.simonbinder.eu), an SQLite ORM.
Add this to your package's `pubspec.yaml` file, using the latest version. Add this to your package's `pubspec.yaml` file, using the latest version.
@@ -21,7 +21,7 @@ Make sure to check [this section](https://getstream.io/chat/docs/flutter-dart/pu
### Setup FCM ### Setup FCM
To integrate push notifications in your Flutter app you need to use the package [firebase_messaging](https://pub.dev/packages/firebase_messaging). To integrate push notifications in your Flutter app you need to use the package [`firebase_messaging`](https://pub.dev/packages/firebase_messaging).
Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to know how to set up the plugin for both Android and iOS. Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to know how to set up the plugin for both Android and iOS.
@@ -61,7 +61,7 @@ Upload the `Server Key` in your chat dashboard
:::note :::note
We are setting up the Android section, but this will work for both Android and iOS if you're using Firebase for both of them! We are setting up the Android section, but this will work for both Android and iOS if you're using Firebase for both of them.
::: :::
#### Step 6 #### Step 6
@@ -97,21 +97,21 @@ firebaseMessaging.onTokenRefresh.listen((token) {
### Possible issues ### Possible issues
We only send push notifications when the user doesn't have any active websocket connection (which is established when you call `client.connectUser`). If you set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) property of the StreamChat widget, when your app goes to background, your device will keep the ws connection alive for 1 minute, and so within this period, you won't receive any push notification. We only send push notifications when the user doesn't have any active web socket connection (which is established when you call `client.connectUser`). If you set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) property of the StreamChat widget, when your app goes to background, your device will keep the WS connection alive for 1 minute, and so within this period, you won't receive any push notification.
Make sure to read the [general push docs](https://getstream.io/chat/docs/flutter-dart/push_introduction/?language=dart) in order to avoid known gotchas that may make your relationship with notifications go bad 😢 Make sure to read the [general push docs](https://getstream.io/chat/docs/flutter-dart/push_introduction/?language=dart) in order to avoid known gotchas that may make your relationship with notifications go bad 😢
### Testing if Push Notifications are Setup Correctly ### Testing if Push Notifications are Setup Correctly
If you're not sure if you've set up push notifications correctly (e.g. you don't always receive them, they work unreliably), you can follow these steps to make sure your config is correct and working: If you're not sure if you've set up push notifications correctly (for example you don't always receive them, they work unreliably), you can follow these steps to make sure your configuration is correct and working:
1. Clone our repo for push testing git clone git@github.com:GetStream/chat-push-test.git 1. Clone our repository for push testing git clone git@github.com:GetStream/chat-push-test.git
2. `cd flutter` 2. `cd flutter`
3. In folder run `flutter pub get` 3. In folder run `flutter pub get`
4. Input your api key and secret in `lib/main.dart` 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 in your device (**do not** run on iOS simulator, Android emulator is fine) 5. Change the bundle identifier/application ID and development team/user so you can run the app in your device (**do not** run on iOS simulator, Android emulator is fine)
@@ -137,11 +137,11 @@ You should get a test push notification
The [StreamChat](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat-class.html) widget lets you define a [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) handler in order to handle events while the app is in the background, but the client is still connected. The [StreamChat](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat-class.html) widget lets you define a [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) handler in order to handle events while the app is in the background, but the client is still connected.
This is useful because it lets you keep the connection alive in cases in which the app goes in the background just for some seconds (eg: multitasking, picking pictures from the gallery...) This is useful because it lets you keep the connection alive in cases in which the app goes in the background just for some seconds (for example multitasking, picking pictures from the gallery...)
You can even customize the [backgroundKeepAlive](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/backgroundKeepAlive.html) duration. You can even customize the [backgroundKeepAlive](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/backgroundKeepAlive.html) duration.
In order to show notifications in such a case we suggest using the package [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications); follow the package guide to successfully set up the plugin. In order to show notifications in such a case we suggest using the package [`flutter_local_notifications`](https://pub.dev/packages/flutter_local_notifications); follow the package guide to successfully set up the plugin.
Once that's done you should set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html); here is an example: Once that's done you should set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html); here is an example:
@@ -234,7 +234,7 @@ To do this we need to update the push notification data payload at Stream Dashbo
} }
``` ```
Then we need to integrate the package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, learn [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up. Then we need to integrate the package [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, learn [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up.
Then during the call `firebaseMessaging.configure(...)` we need to set the `onBackgroundMessage` parameter using a TOP-LEVEL or STATIC function to handle background messages; here is an example: Then during the call `firebaseMessaging.configure(...)` we need to set the `onBackgroundMessage` parameter using a TOP-LEVEL or STATIC function to handle background messages; here is an example:
@@ -17,7 +17,7 @@ You can read more about Streams [push delivery logic](https://getstream.io/ch
### Setup FCM ### Setup FCM
To integrate push notifications in your Flutter app, you need to use the package [firebase_messaging](https://pub.dev/packages/firebase_messaging). To integrate push notifications in your Flutter app, you need to use the package [`firebase_messaging`](https://pub.dev/packages/firebase_messaging).
Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to set up the plugin for Android and iOS. Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to set up the plugin for Android and iOS.
@@ -55,7 +55,7 @@ You can upload your Firebase credentials using either the dashboard or the app s
![](../assets/firebase_notifications_toggle-5aeabfcbdc24cb8f1fea7d41d0e845fc.png) ![](../assets/firebase_notifications_toggle-5aeabfcbdc24cb8f1fea7d41d0e845fc.png)
3. Enter your Firebase Credentials and press "Save". 3. Enter your Firebase Credentials and press `"Save"`.
##### Using the API ##### Using the API
@@ -97,7 +97,7 @@ On iOS we send both a **notification** and a **data** payload.
This means you don't need to do anything special to get the notification to show up. However, you might want to handle the data payload to perform some logic when the user taps on the notification. This means you don't need to do anything special to get the notification to show up. However, you might want to handle the data payload to perform some logic when the user taps on the notification.
To update the template, you can use a backend SDK. To update the template, you can use a backend SDK.
For example, using the javascript SDK: For example, using the JavaScript SDK:
```js ```js
const client = StreamChat.getInstance(api_key, api_secret); const client = StreamChat.getInstance(api_key, api_secret);
@@ -173,13 +173,13 @@ void handleNotification(
FirebaseMessaging.onBackgroundMessage(onBackgroundMessage); FirebaseMessaging.onBackgroundMessage(onBackgroundMessage);
``` ```
In the above example, you get the message details using the `getMessage` method and then you use the [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications) package to show the actual notification. In the above example, you get the message details using the `getMessage` method and then you use the [`flutter_local_notifications`](https://pub.dev/packages/flutter_local_notifications) package to show the actual notification.
##### Using a Template on Android ##### Using a Template on Android
It's still possible to add a **notification** payload to Android notifications. It's still possible to add a **notification** payload to Android notifications.
You can do so by adding a template using a backend SDK. You can do so by adding a template using a backend SDK.
For example, using the javascript SDK: For example, using the JavaScript SDK:
```js ```js
const client = StreamChat.getInstance(api_key, api_secret); const client = StreamChat.getInstance(api_key, api_secret);
@@ -203,11 +203,11 @@ Make sure to read the [general push notification docs](https://getstream.io/chat
### Testing if Push Notifications are Setup Correctly ### Testing if Push Notifications are Setup Correctly
If you're not sure whether you've set up push notifications correctly, for example, you don't always receive them, or they dont work reliably, then you can follow these steps to make sure your config is correct and working: If you're not sure whether you've set up push notifications correctly, for example, you don't always receive them, or they dont work reliably, then you can follow these steps to make sure your configuration is correct and working:
1. Clone our repo for push testing: `git clone git@github.com:GetStream/chat-push-test.git` 1. Clone our repository for push testing: `git clone git@github.com:GetStream/chat-push-test.git`
2. `cd flutter` 2. `cd flutter`
3. In that folder run `flutter pub get` 3. In that folder run `flutter pub get`
4. Input your api key and secret in `lib/main.dart` 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. 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.
6. Add your `google-services.json/GoogleService-Info.plist` 6. Add your `google-services.json/GoogleService-Info.plist`
7. Run the app 7. Run the app
@@ -249,7 +249,7 @@ Take a look at the [Stream Chat v1 sample app](https://github.com/GetStream/flut
When the app is closed you may want to save received messages when you receive them via a notification so that later on when you open the app they're already there. When the app is closed you may want to save received messages when you receive them via a notification so that later on when you open the app they're already there.
To do this you need to integrate the package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, see [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up. To do this you need to integrate the package [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, see [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up.
Then calling `FirebaseMessaging.onBackgroundMessage(...)` you need to use a TOP-LEVEL or STATIC function to handle background messages; here is an example: Then calling `FirebaseMessaging.onBackgroundMessage(...)` you need to use a TOP-LEVEL or STATIC function to handle background messages; here is an example:
@@ -37,7 +37,7 @@ Additionally, pinning a message requires you to add the roles which are allowed
### Partially remove some message actions ### Partially remove some message actions
For example, if you only want to keep "copy message" and "delete message", For example, if you only want to keep `"copy message"` and `"delete message"`,
here is how to do it using the `messageBuilder` with our `MessageWidget`. here is how to do it using the `messageBuilder` with our `MessageWidget`.
```dart ```dart
@@ -36,7 +36,7 @@ Check out the diagram below for an example:
### Dependencies ### Dependencies
Add the [webcrypto](https://pub.dev/packages/webcrypto) package in your `pubspec.yaml` file. Add the [`webcrypto`](https://pub.dev/packages/webcrypto) package in your `pubspec.yaml` file.
```yaml ```yaml
dependencies: dependencies:
@@ -76,9 +76,9 @@ class JsonWebKeyPair {
} }
``` ```
### Generate a Crypto Key ### Generate a Cryptographic Key
Next, create a symmetric **Crypto Key** using the keys generated in the previous step. Next, create a symmetric **Cryptographic Key** using the keys generated in the previous step.
You will use those keys to encrypt and decrypt messages. You will use those keys to encrypt and decrypt messages.
```dart ```dart
@@ -107,7 +107,7 @@ Future<List<int>> deriveKey(String senderJwk, String receiverJwk) async {
### Encrypting Messages ### Encrypting Messages
Once you have generated the **Crypto Key**, you're ready to encrypt the message. Once you have generated the **Cryptographic Key**, you're ready to encrypt the message.
You can use the **AES-GCM** algorithm for its known security and performance balance and good browser availability. You can use the **AES-GCM** algorithm for its known security and performance balance and good browser availability.
```dart ```dart
@@ -253,6 +253,6 @@ MessageListView(
), ),
``` ```
That's it! That's all you need to implement E2EE in a Stream powered chat app. That's it. That's all you need to implement E2EE in a Stream powered chat app.
For more details, check out our [end-to-end encrypted chat article](https://getstream.io/blog/end-to-end-encrypted-chat-in-flutter/#whats-end-to-end-encryption). For more details, check out our [end-to-end encrypted chat article](https://getstream.io/blog/end-to-end-encrypted-chat-in-flutter/#whats-end-to-end-encryption).
@@ -75,7 +75,7 @@ Added video compress options (frame and quality) to MessageInput
`TypingIndicator` now has a property called `parentId` to show typing indicator specific to threads `TypingIndicator` now has a property called `parentId` to show typing indicator specific to threads
#493: add support for `MessageListView` header/footer #493: add support for `MessageListView` header/footer
`MessageWidget` accepts a `userAvatarBuilder` `MessageWidget` accepts a `userAvatarBuilder`
Added `pinMessage` ui support Added `pinMessage` UI support
Added `MessageListView.threadSeparatorBuilder` property Added `MessageListView.threadSeparatorBuilder` property
Added `MessageInput.onError` property to allow error handling Added `MessageInput.onError` property to allow error handling
Added `GalleryHeader`/`GalleryFooter` theme classes Added `GalleryHeader`/`GalleryFooter` theme classes
@@ -202,20 +202,20 @@ in the constructor)
#### 🛑️ Breaking Changes from 1.5.3 #### 🛑️ Breaking Changes from 1.5.3
* Migrate this package to null safety * Migrate this package to null safety
* `ConnectUserWithProvider` now requires `tokenProvider` as a required param. (Removed from the constructor) * `ConnectUserWithProvider` now requires `tokenProvider` as a required parameter. (Removed from the constructor)
* `client.disconnect()` is now divided into two different functions * `client.disconnect()` is now divided into two different functions
* `client.closeConnection()` -> for closing user websocket connection. * `client.closeConnection()` -> for closing user web socket connection.
* `client.disconnectUser()` -> for disconnecting user and resetting client state. * `client.disconnectUser()` -> for disconnecting user and resetting client state.
* `client.devToken()` now returns a Token model instead of String. * `client.devToken()` now returns a Token model instead of String.
* `ApiError` is removed in favor of `StreamChatError` * `ApiError` is removed in favor of `StreamChatError`
* `StreamChatError` -> parent type for all the stream errors. * `StreamChatError` -> parent type for all the stream errors.
* `StreamWebSocketError` -> for user websocket related errors. * `StreamWebSocketError` -> for user web socket related errors.
* `StreamChatNetworkError` -> for network related errors. * `StreamChatNetworkError` -> for network related errors.
* `client.queryChannels()`, `channel.query()` options param is removed in favor of individual params * `client.queryChannels()`, `channel.query()` options parameter is removed in favor of individual parameters
* `option.state` -> `bool state` * `option.state` -> `bool state`
* `option.watch` -> `bool watch` * `option.watch` -> `bool watch`
* `option.presence` -> `bool presence` * `option.presence` -> `bool presence`
* `client.queryUsers()` options param is removed in favor of individual params * `client.queryUsers()` options parameter is removed in favor of individual parameters
* `option.presence` -> `bool presence` * `option.presence` -> `bool presence`
* Added typed filters * Added typed filters
@@ -227,8 +227,8 @@ in the constructor)
#### ✅ Added #### ✅ Added
* New Location enum is introduced for easily changing the client location/baseUrl. * New Location `enum` is introduced for easily changing the client location/baseUrl.
* New `client.openConnection()` and `client.closeConnection()` is introduced to connect/disconnect user ws connection. * New `client.openConnection()` and `client.closeConnection()` is introduced to connect/disconnect user WS connection.
* New `client.partialUpdateMessage` and `channel.partialUpdateMessage` methods * New `client.partialUpdateMessage` and `channel.partialUpdateMessage` methods
* `connectWebSocket` parameter in connect user calls to use the client in "connection-less" mode. * `connectWebSocket` parameter in connect user calls to use the client in "connection-less" mode.
@@ -253,29 +253,29 @@ dependencies:
Upon doing this, all breaking changes from the package will take immediate effect. Here are steps to Upon doing this, all breaking changes from the package will take immediate effect. Here are steps to
remedy the issues: remedy the issues:
1) Change over the constructor of `connectUserWithProvider()` to the new format which has `tokenProvider` as a required param. 1) Change over the constructor of `connectUserWithProvider()` to the new format which has `tokenProvider` as a required parameter.
2) We added more nuance to `disconnectUser()` by adding two new methods - one to close the connection 2) We added more nuance to `disconnectUser()` by adding two new methods - one to close the connection
and the other to disconnect the user. This allows more fine-grained control of disconnection. and the other to disconnect the user. This allows more fine-grained control of disconnection.
* `client.closeConnection()` -> for closing user websocket connection. * `client.closeConnection()` -> for closing user web socket connection.
* `client.disconnectUser()` -> for disconnecting user and resetting client state. * `client.disconnectUser()` -> for disconnecting user and resetting client state.
3) We refactored how we handle errors - new error types are now introduced that replace ApiError. 3) We refactored how we handle errors - new error types are now introduced that replace ApiError.
* `StreamChatError` -> parent type for all the stream errors. * `StreamChatError` -> parent type for all the stream errors.
* `StreamWebSocketError` -> for user websocket related errors. * `StreamWebSocketError` -> for user web socket related errors.
* `StreamChatNetworkError` -> for network related errors. * `StreamChatNetworkError` -> for network related errors.
4) We changed over from a map full of options to a more type-safe and sound approach by changing over to explicit parameters. 4) We changed over from a map full of options to a more type-safe and sound approach by changing over to explicit parameters.
Use these explicit parameters in the query parameters instead of the option keys: Use these explicit parameters in the query parameters instead of the option keys:
* `client.queryChannels()`, `channel.query()` options param is removed in favor of individual params * `client.queryChannels()`, `channel.query()` options parameter is removed in favor of individual parameters
* `option.state` -> `bool state` * `option.state` -> `bool state`
* `option.watch` -> `bool watch` * `option.watch` -> `bool watch`
* `option.presence` -> `bool presence` * `option.presence` -> `bool presence`
* `client.queryUsers()` options param is removed in favor of individual params * `client.queryUsers()` options parameter is removed in favor of individual parameters
* `option.presence` -> `bool presence` * `option.presence` -> `bool presence`
5) We added type-safe filters to make filtering in the app easier. Change over the filters to the 5) We added type-safe filters to make filtering in the app easier. Change over the filters to the
@@ -24,7 +24,7 @@ Filter.equal('type', 'messaging'),
#### Filter.notEqual #### Filter.notEqual
The 'notEqual' filter gets the objects where the given key does not have the specified value. The `notEqual` filter gets the objects where the given key does not have the specified value.
```dart ```dart
Filter.notEqual('type', 'messaging'), Filter.notEqual('type', 'messaging'),
@@ -64,20 +64,20 @@ Filter.lessOrEqual('count', 5),
#### Filter.in_ #### Filter.in_
The 'in_' filter allows getting objects where the key matches any in a specified array. The ``in_` filter allows getting objects where the key matches any in a specified array.
```dart ```dart
Filter.in_('members', [user.id]) Filter.in_('members', [user.id])
``` ```
:::note :::note
Since 'in' is a keyword in Dart, the filter has an underscore added. This does not apply to the 'notIn' Since `in` is a keyword in Dart, the filter has an underscore added. This does not apply to the `notIn`
keyword. keyword.
::: :::
#### Filter.notIn #### Filter.notIn
The 'notIn' filter allows getting objects where the key matches none in a specified array. The `notIn` filter allows getting objects where the key matches none in a specified array.
```dart ```dart
Filter.notIn('members', [user.id]) Filter.notIn('members', [user.id])
@@ -109,7 +109,7 @@ Filter.exists('name')
#### Filter.notExists #### Filter.notExists
The 'notExists' filter checks if the specified key doesn't exist. This is a simplified call to `Filter.exists` The `notExists` filter checks if the specified key doesn't exist. This is a simplified call to `Filter.exists`
with the value set to false. with the value set to false.
```dart ```dart
@@ -155,7 +155,7 @@ Running the above will give this:
![](../assets/authentication_demo_app.jpg) ![](../assets/authentication_demo_app.jpg)
The `Auth` widget handles all of the authentication logic. It initializes a `FirebaseAuth.instance` and uses that The `Auth` widget handles all of the authentication logic. It initializes a `FirebaseAuth.instance` and uses that
in the `createAccount`, `signIn` and `signOut` methods. There is a button to envoke each of these methods. in the `createAccount`, `signIn` and `signOut` methods. There is a button to invoke each of these methods.
The `FirebaseFunctions.instance` will be used later in this guide. The `FirebaseFunctions.instance` will be used later in this guide.
@@ -289,7 +289,7 @@ firebase deploy --only functions
### Create a Stream User and Get the User's Token ### Create a Stream User and Get the User's Token
In the `createStreamUserAndGetToken` cloud function you create an `onCall` HTTPS handler, which exposes In the `createStreamUserAndGetToken` cloud function you create an `onCall` HTTPS handler, which exposes
a cloud function that can be envoked from your Flutter app. a cloud function that can be invoked from your Flutter app.
```js ```js
// Create a Stream user and return auth token. // Create a Stream user and return auth token.
@@ -325,13 +325,13 @@ by ensuring that `context.auth` is not null. If it is null, then it throws an `H
message. This error can be caught in your Flutter application. message. This error can be caught in your Flutter application.
If the caller is authenticated the function proceeds to use the `serverClient` to create a new Stream Chat If the caller is authenticated the function proceeds to use the `serverClient` to create a new Stream Chat
user by calling the `upsertUser` method and passing in some user data. It uses the authenticated caller's **uid** as an **id**. user by calling the `upsertUser` method and passing in some user data. It uses the authenticated caller's **`uid`** as an **id**.
After the user is created it generates a token for that user. This token is then returned to the caller. After the user is created it generates a token for that user. This token is then returned to the caller.
To call this from Flutter, you will need to use the `cloud_functions` package. To call this from Flutter, you will need to use the `cloud_functions` package.
Update the **createAccount** method in your Flutter code to the following: Update the **`createAccount`** method in your Flutter code to the following:
```dart ```dart
Future<void> createAccount() async { Future<void> createAccount() async {
@@ -355,7 +355,7 @@ in the request.
Once you have the Stream user token, you can authenticate your Stream Chat user as you normally would. Once you have the Stream user token, you can authenticate your Stream Chat user as you normally would.
Please see our [initialization documention](https://getstream.io/chat/docs/flutter-dart/init_and_users/?language=dart) for more information. Please see our [initialization documentation](https://getstream.io/chat/docs/flutter-dart/init_and_users/?language=dart) for more information.
As you can see below, the User ID matches on both Firebase's and Stream's user database. As you can see below, the User ID matches on both Firebase's and Stream's user database.
@@ -373,7 +373,7 @@ As you can see below, the User ID matches on both Firebase's and Stream's user d
The `getStreamUserToken` cloud function is very similar to the `createStreamUserAndGetToken` function. The only difference is The `getStreamUserToken` cloud function is very similar to the `createStreamUserAndGetToken` function. The only difference is
that it only creates a user token and does not create a new user account on Stream. that it only creates a user token and does not create a new user account on Stream.
Update the **signIn** method in your Flutter code to the following: Update the **`signIn`** method in your Flutter code to the following:
```dart ```dart
Future<void> signIn() async { Future<void> signIn() async {
@@ -434,7 +434,7 @@ exports.deleteStreamUser = functions.auth.user().onDelete((user, context) => {
``` ```
In this function, you are listening to delete events on Firebase auth. When an account is deleted, this function will be triggered, and you can get the In this function, you are listening to delete events on Firebase auth. When an account is deleted, this function will be triggered, and you can get the
user's **uid** and call the `deleteUser` method on the `serverClient`. user's **`uid`** and call the `deleteUser` method on the `serverClient`.
This is not an external cloud function; it can only be triggered when an This is not an external cloud function; it can only be triggered when an
account is deleted. account is deleted.
@@ -60,7 +60,7 @@ ChannelListHeader(
![](../assets/channel_list_header_custom_subtitle.png) ![](../assets/channel_list_header_custom_subtitle.png)
The `titleBuilder` param helps you build different titles depending on the connection state: The `titleBuilder` parameter helps you build different titles depending on the connection state:
```dart ```dart
//... //...
@@ -25,7 +25,7 @@ widget.
### Basic Example ### Basic Example
Here is a basic example of the `ChannelListView` widget. It consists of the main widget itself, a `Filter` Here is a basic example of the `ChannelListView` widget. It consists of the main widget itself, a `Filter`
to filter only the channels that the user is a part of, sorting by last message time, pagination params, to filter only the channels that the user is a part of, sorting by last message time, pagination parameters,
and the widget to use when a particular channel is clicked. and the widget to use when a particular channel is clicked.
```dart ```dart
@@ -54,7 +54,7 @@ the widget.
### Customizing the Channel Preview ### Customizing the Channel Preview
A common aspect of the widget needed to be tweaked according to each app is the Channel Preview (the A common aspect of the widget needed to be tweaked according to each app is the Channel Preview (the
Channel tile in the list). To do this, we use the `channelPreviewBuilder` param like this: Channel tile in the list). To do this, we use the `channelPreviewBuilder` parameter like this:
```dart ```dart
ChannelListView( ChannelListView(
@@ -90,7 +90,7 @@ This adds two basic actions - info and delete:
![](../assets/swipe_channel.png) ![](../assets/swipe_channel.png)
To add custom actions of your own, use the `swipeActions` param: To add custom actions of your own, use the `swipeActions` parameter:
```dart ```dart
ChannelListView( ChannelListView(
@@ -41,8 +41,8 @@ which will be addressed by the respective plugin creators over time.
The library uses [flutter file picker plugin](https://github.com/miguelpruivo/flutter_file_picker) to pick files from the os. The library uses [flutter file picker plugin](https://github.com/miguelpruivo/flutter_file_picker) to pick files from the os.
Follow [this wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#ios) to fulfill iOS requirements. Follow [this wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#ios) to fulfill iOS requirements.
We also use [video_player](https://pub.dev/packages/video_player) to reproduce videos. We also use [`video_player`](https://pub.dev/packages/video_player) to reproduce videos.
Follow [this guide](https://pub.dev/packages/video_player#installation) to fulfill the requirements. Follow [this guide](https://pub.dev/packages/video_player#installation) to fulfill the requirements.
To pick images from the camera, we use the [image_picker](https://pub.dev/packages/image_picker) plugin. To pick images from the camera, we use the [`image_picker`](https://pub.dev/packages/image_picker) plugin.
Follow [these instructions](https://pub.dev/packages/image_picker#ios) to check the requirements. Follow [these instructions](https://pub.dev/packages/image_picker#ios) to check the requirements.
@@ -13,7 +13,7 @@ according to the filters and sort order given. However, in some cases, implement
that cannot be done using the customization approaches given in the widget. 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 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 fetches channels in the expected way via the usual parameters 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. exposes builders to build the UI in situations such as loading, empty data, errors, and on data received.
### Basic Example ### Basic Example
@@ -13,7 +13,7 @@ according to the filters and sort order given. However, in some cases, implement
that cannot be done using the customization approaches given in the widget. 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 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 fetches channels in the expected way via the usual parameters 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. exposes builders to build the UI in situations such as loading, empty data, errors, and on data received.
### Basic Example ### Basic Example
@@ -13,7 +13,7 @@ according to the filters and sort order given. However, in some cases, implement
that cannot be done using the customization approaches given in the widget. 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 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 fetches channels in the expected way via the usual parameters 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. exposes builders to build the UI in situations such as loading, empty data, errors, and on data received.
### Basic Example ### Basic Example
@@ -9,7 +9,7 @@ theme and initialisations.
`StreamChatCore` is used to provide information about the chat client to the widget tree. `StreamChatCore` is used to provide information about the chat client to the widget tree.
This Widget is used to react to life cycle changes and system updates. This Widget is used to react to life cycle changes and system updates.
When the app goes into the background, the websocket connection is automatically closed and when it goes back to foreground the connection is opened again. When the app goes into the background, the web socket connection is automatically closed and when it goes back to foreground the connection is opened again.
Like the `StreamChat` widget in the higher level UI package, the `StreamChatCore` widget should Like the `StreamChat` widget in the higher level UI package, the `StreamChatCore` widget should
be on the top level before using any Stream functionality: be on the top level before using any Stream functionality:
@@ -13,7 +13,7 @@ according to the filters and sort order given. However, in some cases, implement
that cannot be done using the customization approaches given in the widget. 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 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 fetches channels in the expected way via the usual parameters 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. exposes builders to build the UI in situations such as loading, empty data, errors, and on data received.
### Basic Example ### Basic Example
@@ -14,7 +14,7 @@ which allows you persist data locally which works with all packages.
### How do I choose? ### How do I choose?
#### The case for stream_chat_flutter #### The case for `stream_chat_flutter`
For the quickest way to integrate Stream Chat with your app, the UI SDK (`stream_chat_flutter`) is the For the quickest way to integrate Stream Chat with your app, the UI SDK (`stream_chat_flutter`) is the
way to go. `stream_chat_flutter` contains prebuilt components that manage most operations like data way to go. `stream_chat_flutter` contains prebuilt components that manage most operations like data
@@ -30,26 +30,26 @@ to request this through our support channels.
<b>Summary:</b> <b>Summary:</b>
For the quickest and easiest way to add Chat to your app with prebuilt UI components, use stream_chat_flutter For the quickest and easiest way to add Chat to your app with prebuilt UI components, use `stream_chat_flutter`
#### The case for stream_chat_flutter_core #### The case for `stream_chat_flutter_core`
If your application involves UI that does not fit in with the stream_chat_flutter components, stream_chat_flutter_core If your application involves UI that does not fit in with the `stream_chat_flutter` components, `stream_chat_flutter_core`
strips away the UI associated with the components and provides the data fetching and manipulation strips away the UI associated with the components and provides the data fetching and manipulation
capabilities while supplying builders for UI. This allows you to implement your own UI and themes capabilities while supplying builders for UI. This allows you to implement your own UI and themes
completely independently while not worrying about writing functions for data and pagination. completely independently while not worrying about writing functions for data and pagination.
<b>Summary:</b> <b>Summary:</b>
For implementing your own custom UI while not having to worry about lower level API calls, use stream_chat_flutter_core. For implementing your own custom UI while not having to worry about lower level API calls, use `stream_chat_flutter_core`.
#### The case for stream_chat #### The case for `stream_chat`
The stream_chat package is the Low-level Client (LLC) of Stream Chat in Flutter. This package wraps The `stream_chat` package is the Low-level Client (LLC) of Stream Chat in Flutter. This package wraps
the underlying functionality of Stream Chat and allows the most customization in terms of UI, data, the underlying functionality of Stream Chat and allows the most customization in terms of UI, data,
and architecture. and architecture.
<b>Summary:</b> <b>Summary:</b>
For the most control over the SDK and dealing with low level calls to the API, use stream_chat. For the most control over the SDK and dealing with low level calls to the API, use `stream_chat`.
@@ -20,18 +20,18 @@ giving you complete control to ones that give you a rich out-of-the-box chat exp
The packages that make up the Stream Chat SDK are: The packages that make up the Stream Chat SDK are:
1. <b>Low Level Client (stream_chat)</b>: a pure Dart package that can be used on any Dart project. 1. <b>Low Level Client (stre`am_chat)</b>: a pure Dart package that can be used on any Dart project.
It provides a low-level client to access the Stream Chat service. It provides a low-level client to access the Stream Chat service.
2. <b>Core (stream_chat_flutter_core)</b>: provides business logic to fetch common things required 2. <b>Core (`stream_chat_flutter_core`)</b>: provides business logic to fetch common things required
for integrating Stream Chat into your application. for integrating Stream Chat into your application.
The core package allows more customisation and hence provides business logic but no UI components. The core package allows more customisation and hence provides business logic but no UI components.
3. <b>UI (stream_chat_flutter)</b>: this library includes both a low-level chat SDK and a set of 3. <b>UI (`stream_chat_flutter`)</b>: this library includes both a low-level chat SDK and a set of
reusable and customisable UI components. reusable and customizable UI components.
4. <b>Persistence (stream_chat_persistence)</b>: provides a persistence client for fetching and 4. <b>Persistence (`stream_chat_persistence`)</b>: provides a persistence client for fetching and
saving chat data locally. saving chat data locally.
5. <b>Localizations (stream_chat_localizations)</b>: provides a set of localizations for the SDK. 5. <b>Localizations (`stream_chat_localizations`)</b>: provides a set of localizations for the SDK.
We recommend building prototypes using the full UI package, [stream_chat_flutter](https://pub.dev/packages/stream_chat_flutter), We recommend building prototypes using the full UI package, [`stream_chat_flutter`](https://pub.dev/packages/stream_chat_flutter),
since it contains UI widgets already integrated with Stream's API. It is the fastest way to get up since it contains UI widgets already integrated with Stream's API. It is the fastest way to get up
and running using Stream chat in your app. and running using Stream chat in your app.
@@ -39,7 +39,7 @@ The Flutter SDK enables you to build any type of chat or messaging experience fo
and Desktop. and Desktop.
If you're building a very custom UI and would prefer a more lean package, If you're building a very custom UI and would prefer a more lean package,
[stream_chat_flutter_core](https://pub.dev/packages/stream_chat_flutter_core) will be suited to this [`stream_chat_flutter_core`](https://pub.dev/packages/stream_chat_flutter_core) will be suited to this
use case. Core allows you to build custom, expressive UIs while retaining the benefits of our full use case. Core allows you to build custom, expressive UIs while retaining the benefits of our full
Flutter SDK. APIs for accessing and controlling users, sending messages, and so forth are seamlessly integrated Flutter SDK. APIs for accessing and controlling users, sending messages, and so forth are seamlessly integrated
into this package and accessible via providers and builders. into this package and accessible via providers and builders.
@@ -69,7 +69,7 @@ While this is a simplistic overview of the service, the Flutter SDK handles the
Before reading the docs, consider trying our [online API tour](https://getstream.io/chat/get_started/), Before reading the docs, consider trying our [online API tour](https://getstream.io/chat/get_started/),
it is a nice way to learn how the API works. it is a nice way to learn how the API works.
It's in-browser so you'll need to use Javascript but the core conceps are pretty much the same as Dart. It's in-browser so you'll need to use JavaScript but the core concepts are pretty much the same as Dart.
You may also like to look at the [Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) You may also like to look at the [Flutter tutorial](https://getstream.io/chat/flutter/tutorial/)
which focuses on using the UI package to get Stream Chat integrated into a Flutter app. which focuses on using the UI package to get Stream Chat integrated into a Flutter app.
@@ -4,7 +4,7 @@ sidebar_position: 3
title: Versioning Policy title: Versioning Policy
--- ---
All of the Stream Chat packages follow [semantic versioning (semver)](https://semver.org/). All of the Stream Chat packages follow [semantic versioning](https://semver.org/).
That means that with a version number x.y.z (major.minor.patch): That means that with a version number x.y.z (major.minor.patch):
- When releasing bug fixes (backwards compatible), we make a patch release by changing the z number (ex: 3.6.2 to 3.6.3). A bug fix is defined as an internal change that fixes incorrect behavior. - When releasing bug fixes (backwards compatible), we make a patch release by changing the z number (ex: 3.6.2 to 3.6.3). A bug fix is defined as an internal change that fixes incorrect behavior.
@@ -27,7 +27,7 @@ Let's build an example of location sharing option in the app:
![](../assets/location_sharing_example.jpg) ![](../assets/location_sharing_example.jpg)
* Show a "Share Location" button next to StreamMessageInput Textfield. * Show a "Share Location" button next to StreamMessageInput `Textfield`.
* When the user presses this button, it should fetch the current location coordinates of the user, and send a message on the channel as follows: * When the user presses this button, it should fetch the current location coordinates of the user, and send a message on the channel as follows:
@@ -47,7 +47,7 @@ Message(
) )
``` ```
For our example, we are going to use [geolocator](https://pub.dev/packages/geolocator) library. For our example, we are going to use [`geolocator`](https://pub.dev/packages/geolocator) library.
Please check their [setup instructions](https://pub.dev/packages/geolocator) on their docs. Please check their [setup instructions](https://pub.dev/packages/geolocator) on their docs.
NOTE: If you are testing on iOS simulator, you will need to set some dummy coordinates, as mentioned [here](https://stackoverflow.com/a/31238119/7489541). NOTE: If you are testing on iOS simulator, you will need to set some dummy coordinates, as mentioned [here](https://stackoverflow.com/a/31238119/7489541).
@@ -55,7 +55,7 @@ Also don't forget to enable "location update" capability in background mode, fro
On the receiver end, `location` type attachment should be rendered in map view, in the `StreamMessageListView`. On the receiver end, `location` type attachment should be rendered in map view, in the `StreamMessageListView`.
We are going to use [Google Static Maps API](https://developers.google.com/maps/documentation/maps-static/overview) to render the map in the message. We are going to use [Google Static Maps API](https://developers.google.com/maps/documentation/maps-static/overview) to render the map in the message.
You can use other libraries as well such as [google_maps_flutter](https://pub.dev/packages/google_maps_flutter). You can use other libraries as well such as [`google_maps_flutter`](https://pub.dev/packages/google_maps_flutter).
First, we add a button which when clicked fetches and shares location into the `MessageInput`: First, we add a button which when clicked fetches and shares location into the `MessageInput`:
@@ -28,7 +28,7 @@ final client = StreamChatClient(
)..chatPersistenceClient = CustomChatPersistentClient(); )..chatPersistenceClient = CustomChatPersistentClient();
``` ```
We provide an official persistent client in the [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) We provide an official persistent client in the [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence)
package that works using the library [moor](https://moor.simonbinder.eu), an SQLite ORM. package that works using the library [moor](https://moor.simonbinder.eu), an SQLite ORM.
Add this to your package's `pubspec.yaml` file, using the latest version. Add this to your package's `pubspec.yaml` file, using the latest version.
@@ -21,7 +21,7 @@ Make sure to check [this section](https://getstream.io/chat/docs/flutter-dart/pu
### Setup FCM ### Setup FCM
To integrate push notifications in your Flutter app you need to use the package [firebase_messaging](https://pub.dev/packages/firebase_messaging). To integrate push notifications in your Flutter app you need to use the package [`firebase_messaging`](https://pub.dev/packages/firebase_messaging).
Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to know how to set up the plugin for both Android and iOS. Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to know how to set up the plugin for both Android and iOS.
@@ -61,7 +61,7 @@ Upload the `Server Key` in your chat dashboard
:::note :::note
We are setting up the Android section, but this will work for both Android and iOS if you're using Firebase for both of them! We are setting up the Android section, but this will work for both Android and iOS if you're using Firebase for both of them.
::: :::
#### Step 6 #### Step 6
@@ -97,21 +97,21 @@ firebaseMessaging.onTokenRefresh.listen((token) {
### Possible issues ### Possible issues
We only send push notifications when the user doesn't have any active websocket connection (which is established when you call `client.connectUser`). If you set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) property of the StreamChat widget, when your app goes to background, your device will keep the ws connection alive for 1 minute, and so within this period, you won't receive any push notification. We only send push notifications when the user doesn't have any active web socket connection (which is established when you call `client.connectUser`). If you set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) property of the StreamChat widget, when your app goes to background, your device will keep the WS connection alive for 1 minute, and so within this period, you won't receive any push notification.
Make sure to read the [general push docs](https://getstream.io/chat/docs/flutter-dart/push_introduction/?language=dart) in order to avoid known gotchas that may make your relationship with notifications go bad 😢 Make sure to read the [general push docs](https://getstream.io/chat/docs/flutter-dart/push_introduction/?language=dart) in order to avoid known gotchas that may make your relationship with notifications go bad 😢
### Testing if Push Notifications are Setup Correctly ### Testing if Push Notifications are Setup Correctly
If you're not sure if you've set up push notifications correctly (e.g. you don't always receive them, they work unreliably), you can follow these steps to make sure your config is correct and working: If you're not sure if you've set up push notifications correctly (for example you don't always receive them, they work unreliably), you can follow these steps to make sure your configuration is correct and working:
1. Clone our repo for push testing git clone git@github.com:GetStream/chat-push-test.git 1. Clone our repository for push testing git clone git@github.com:GetStream/chat-push-test.git
2. `cd flutter` 2. `cd flutter`
3. In folder run `flutter pub get` 3. In folder run `flutter pub get`
4. Input your api key and secret in `lib/main.dart` 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 in your device (**do not** run on iOS simulator, Android emulator is fine) 5. Change the bundle identifier/application ID and development team/user so you can run the app in your device (**do not** run on iOS simulator, Android emulator is fine)
@@ -137,11 +137,11 @@ You should get a test push notification
The [StreamChat](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat-class.html) widget lets you define a [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) handler in order to handle events while the app is in the background, but the client is still connected. The [StreamChat](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat-class.html) widget lets you define a [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html) handler in order to handle events while the app is in the background, but the client is still connected.
This is useful because it lets you keep the connection alive in cases in which the app goes in the background just for some seconds (eg: multitasking, picking pictures from the gallery...) This is useful because it lets you keep the connection alive in cases in which the app goes in the background just for some seconds (for example multitasking, picking pictures from the gallery...)
You can even customize the [backgroundKeepAlive](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/backgroundKeepAlive.html) duration. You can even customize the [backgroundKeepAlive](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/backgroundKeepAlive.html) duration.
In order to show notifications in such a case we suggest using the package [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications); follow the package guide to successfully set up the plugin. In order to show notifications in such a case we suggest using the package [`flutter_local_notifications`](https://pub.dev/packages/flutter_local_notifications); follow the package guide to successfully set up the plugin.
Once that's done you should set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html); here is an example: Once that's done you should set the [onBackgroundEventReceived](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat/onBackgroundEventReceived.html); here is an example:
@@ -234,7 +234,7 @@ To do this we need to update the push notification data payload at Stream Dashbo
} }
``` ```
Then we need to integrate the package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, learn [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up. Then we need to integrate the package [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, learn [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up.
Then during the call `firebaseMessaging.configure(...)` we need to set the `onBackgroundMessage` parameter using a TOP-LEVEL or STATIC function to handle background messages; here is an example: Then during the call `firebaseMessaging.configure(...)` we need to set the `onBackgroundMessage` parameter using a TOP-LEVEL or STATIC function to handle background messages; here is an example:
@@ -17,7 +17,7 @@ You can read more about Streams [push delivery logic](https://getstream.io/ch
### Setup FCM ### Setup FCM
To integrate push notifications in your Flutter app, you need to use the package [firebase_messaging](https://pub.dev/packages/firebase_messaging). To integrate push notifications in your Flutter app, you need to use the package [`firebase_messaging`](https://pub.dev/packages/firebase_messaging).
Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to set up the plugin for Android and iOS. Follow the [Firebase documentation](https://firebase.flutter.dev/docs/messaging/overview/) to set up the plugin for Android and iOS.
@@ -55,7 +55,7 @@ You can upload your Firebase credentials using either the dashboard or the app s
![](../assets/firebase_notifications_toggle-5aeabfcbdc24cb8f1fea7d41d0e845fc.png) ![](../assets/firebase_notifications_toggle-5aeabfcbdc24cb8f1fea7d41d0e845fc.png)
3. Enter your Firebase Credentials and press "Save". 3. Enter your Firebase Credentials and press `"Save"`.
##### Using the API ##### Using the API
@@ -86,7 +86,7 @@ firebaseMessaging.onTokenRefresh.listen((token) {
}); });
``` ```
Push Notifications v2 also supports specifying a name to the push device tokens you register. By setting the optional `pushProviderName` param in the `addDevice` call you can support different configurations between the device and the `PushProvider`. Push Notifications v2 also supports specifying a name to the push device tokens you register. By setting the optional `pushProviderName` parameter in the `addDevice` call you can support different configurations between the device and the `PushProvider`.
```dart ```dart
firebaseMessaging.onTokenRefresh.listen((token) { firebaseMessaging.onTokenRefresh.listen((token) {
@@ -105,7 +105,7 @@ On iOS we send both a **notification** and a **data** payload.
This means you don't need to do anything special to get the notification to show up. However, you might want to handle the data payload to perform some logic when the user taps on the notification. This means you don't need to do anything special to get the notification to show up. However, you might want to handle the data payload to perform some logic when the user taps on the notification.
To update the template, you can use a backend SDK. To update the template, you can use a backend SDK.
For example, using the javascript SDK: For example, using the JavaScript SDK:
```js ```js
const client = StreamChat.getInstance(api_key, api_secret); const client = StreamChat.getInstance(api_key, api_secret);
@@ -181,13 +181,13 @@ void handleNotification(
FirebaseMessaging.onBackgroundMessage(onBackgroundMessage); FirebaseMessaging.onBackgroundMessage(onBackgroundMessage);
``` ```
In the above example, you get the message details using the `getMessage` method and then you use the [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications) package to show the actual notification. In the above example, you get the message details using the `getMessage` method and then you use the [`flutter_local_notifications`](https://pub.dev/packages/flutter_local_notifications) package to show the actual notification.
##### Using a Template on Android ##### Using a Template on Android
It's still possible to add a **notification** payload to Android notifications. It's still possible to add a **notification** payload to Android notifications.
You can do so by adding a template using a backend SDK. You can do so by adding a template using a backend SDK.
For example, using the javascript SDK: For example, using the JavaScript SDK:
```js ```js
const client = StreamChat.getInstance(api_key, api_secret); const client = StreamChat.getInstance(api_key, api_secret);
@@ -211,11 +211,11 @@ Make sure to read the [general push notification docs](https://getstream.io/chat
### Testing if Push Notifications are Setup Correctly ### Testing if Push Notifications are Setup Correctly
If you're not sure whether you've set up push notifications correctly, for example, you don't always receive them, or they dont work reliably, then you can follow these steps to make sure your config is correct and working: If you're not sure whether you've set up push notifications correctly, for example, you don't always receive them, or they dont work reliably, then you can follow these steps to make sure your configuration is correct and working:
1. Clone our repo for push testing: `git clone git@github.com:GetStream/chat-push-test.git` 1. Clone our repository for push testing: `git clone git@github.com:GetStream/chat-push-test.git`
2. `cd flutter` 2. `cd flutter`
3. In that folder run `flutter pub get` 3. In that folder run `flutter pub get`
4. Input your api key and secret in `lib/main.dart` 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. 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.
6. Add your `google-services.json/GoogleService-Info.plist` 6. Add your `google-services.json/GoogleService-Info.plist`
7. Run the app 7. Run the app
@@ -257,7 +257,7 @@ Take a look at the [Stream Chat v1 sample app](https://github.com/GetStream/flut
When the app is closed you may want to save received messages when you receive them via a notification so that later on when you open the app they're already there. When the app is closed you may want to save received messages when you receive them via a notification so that later on when you open the app they're already there.
To do this you need to integrate the package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, see [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up. To do this you need to integrate the package [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence) in our app that exports a persistence client, see [here](https://pub.dev/packages/stream_chat_persistence#usage) how to set it up.
Then calling `FirebaseMessaging.onBackgroundMessage(...)` you need to use a TOP-LEVEL or STATIC function to handle background messages; here is an example: Then calling `FirebaseMessaging.onBackgroundMessage(...)` you need to use a TOP-LEVEL or STATIC function to handle background messages; here is an example:
@@ -19,7 +19,7 @@ This widget will be used to show the autocomplete options.
For this example we're using two external dependencies: For this example we're using two external dependencies:
- [emojis](https://pub.dev/packages/emojis) - [emojis](https://pub.dev/packages/emojis)
- [substring_highlight](https://pub.dev/packages/substring_highlight) - [`substring_highlight`](https://pub.dev/packages/substring_highlight)
```dart ```dart
import 'package:emojis/emoji.dart'; import 'package:emojis/emoji.dart';
@@ -37,7 +37,7 @@ Additionally, pinning a message requires you to add the roles which are allowed
### Partially remove some message actions ### Partially remove some message actions
For example, if you only want to keep "copy message" and "delete message", For example, if you only want to keep `"copy message"` and `"delete message"`
here is how to do it using the `messageBuilder` with our `StreamMessageWidget`. here is how to do it using the `messageBuilder` with our `StreamMessageWidget`.
```dart ```dart
@@ -36,7 +36,7 @@ Check out the diagram below for an example:
### Dependencies ### Dependencies
Add the [webcrypto](https://pub.dev/packages/webcrypto) package in your `pubspec.yaml` file. Add the [web cryptographic](https://pub.dev/packages/webcrypto) package in your `pubspec.yaml` file.
```yaml ```yaml
dependencies: dependencies:
@@ -76,9 +76,9 @@ class JsonWebKeyPair {
} }
``` ```
### Generate a Crypto Key ### Generate a Cryptographic Key
Next, create a symmetric **Crypto Key** using the keys generated in the previous step. Next, create a symmetric **Cryptographic Key** using the keys generated in the previous step.
You will use those keys to encrypt and decrypt messages. You will use those keys to encrypt and decrypt messages.
```dart ```dart
@@ -107,7 +107,7 @@ Future<List<int>> deriveKey(String senderJwk, String receiverJwk) async {
### Encrypting Messages ### Encrypting Messages
Once you have generated the **Crypto Key**, you're ready to encrypt the message. Once you have generated the **Cryptographic Key**, you're ready to encrypt the message.
You can use the **AES-GCM** algorithm for its known security and performance balance and good browser availability. You can use the **AES-GCM** algorithm for its known security and performance balance and good browser availability.
```dart ```dart
@@ -253,6 +253,6 @@ StreamMessageListView(
), ),
``` ```
That's it! That's all you need to implement E2EE in a Stream powered chat app. That's it. That's all you need to implement E2EE in a Stream powered chat app.
For more details, check out our [end-to-end encrypted chat article](https://getstream.io/blog/end-to-end-encrypted-chat-in-flutter/#whats-end-to-end-encryption). For more details, check out our [end-to-end encrypted chat article](https://getstream.io/blog/end-to-end-encrypted-chat-in-flutter/#whats-end-to-end-encryption).
@@ -13,7 +13,7 @@ If you find any bugs or have any questions, please file an [issue on our GitHub
Code examples: Code examples:
- See our [Stream Chat Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) for an up-to-date guide using the latest Stream Chat version. - See our [Stream Chat Flutter tutorial](https://getstream.io/chat/flutter/tutorial/) for an up-to-date guide using the latest Stream Chat version.
- See the [Stream Flutter Samples repository](https://github.com/GetStream/flutter-samples) with our fully-fledged messaging [sample application](https://github.com/GetStream/flutter-samples/tree/main/packages/stream_chat_v1). - See the [Stream Flutter Samples repository](https://github.com/GetStream/flutter-samples) with our full fledged messaging [sample application](https://github.com/GetStream/flutter-samples/tree/main/packages/stream_chat_v1).
All of our documentation has also been updated to support v4, so all of the guides and examples will have updated code. All of our documentation has also been updated to support v4, so all of the guides and examples will have updated code.
@@ -208,10 +208,10 @@ Let's explore some examples of the functional differences when using the new `St
The **StreamChannelListController** provides various methods, such as: The **StreamChannelListController** provides various methods, such as:
- **deleteChannel** - **`deleteChannel`**
- **loadMore** - **`loadMore`**
- **muteChannel** - **`muteChannel`**
- **deleteChannel** - **`deleteChannel`**
For a complete list with additional information, see the code documentation. For a complete list with additional information, see the code documentation.
@@ -536,7 +536,7 @@ Creating a separate controller allows easier control over the message input cont
The widget is also separated into smaller components: `StreamCountDownButton`, `StreamAttachmentPicker`, etc. The widget is also separated into smaller components: `StreamCountDownButton`, `StreamAttachmentPicker`, etc.
> ❗The `MessageInputController` is exposed by the **stream_chat_flutter_core** package. This allows you to use the controller even if you're not using the UI components. > ❗The `MessageInputController` is exposed by the **`stream_chat_flutter_core`** package. This allows you to use the controller even if you're not using the UI components.
As a result of this extra control, it is no longer needed for the new `StreamMessageInput` widget to expose these `MessageInput` arguments: As a result of this extra control, it is no longer needed for the new `StreamMessageInput` widget to expose these `MessageInput` arguments:
@@ -733,7 +733,7 @@ The controller makes it much simpler to dynamically modify the message input.
## Stream Chat Flutter Core ## Stream Chat Flutter Core
Various changes have been made to the Core package, most notably, the indroduction of all of the controllers mentioned above. Various changes have been made to the Core package, most notably, the introduction of all of the controllers mentioned above.
These controllers replace the business logic implementations (Bloc). Please note that this is not related to the well-known Flutter Bloc package, but instead refers to the naming we used for our business logic components. These controllers replace the business logic implementations (Bloc). Please note that this is not related to the well-known Flutter Bloc package, but instead refers to the naming we used for our business logic components.
@@ -39,7 +39,7 @@ In this example, you are doing a few important things in the ChannelListPage wid
- Using the **flutter_slidable** package to easily add slide functionality. - Using the **flutter_slidable** package to easily add slide functionality.
- Passing in the `itemBuilder` argument for the **StreamChannelListView** widget. This gives access to the current **BuildContext**, **Channel**, and **StreamChannelListTile**, and allows you to create, or customize, the stream channel list tiles. - Passing in the `itemBuilder` argument for the **StreamChannelListView** widget. This gives access to the current **BuildContext**, **Channel**, and **StreamChannelListTile**, and allows you to create, or customize, the stream channel list tiles.
- Returning a Slidable widget with two CustomSlidableAction widgets - to delete a channel and show more options. These widgets come from the flutter_slidable package. - Returning a Slidable widget with two CustomSlidableAction widgets - to delete a channel and show more options. These widgets come from the flutter_slidable package.
- Adding `onPressed` behaviour to call `showConfirmationDialog` and `showChannelInfoModalBottomSheet`. These methods come from the **stream_chat_flutter** package. They have a few different on-tap callbacks you can supply, for example, `onViewInfoTap`. Alternatively, you can create custom dialogs from scratch. - Adding `onPressed` behaviour to call `showConfirmationDialog` and `showChannelInfoModalBottomSheet`. These methods come from the **`stream_chat_flutter`** package. They have a few different on-tap callbacks you can supply, for example, `onViewInfoTap`. Alternatively, you can create custom dialog screens from scratch.
- Using the **StreamChannelListController** to perform actions, such as, `deleteChannel`. - Using the **StreamChannelListController** to perform actions, such as, `deleteChannel`.
```dart ```dart
@@ -24,7 +24,7 @@ Filter.equal('type', 'messaging'),
#### Filter.notEqual #### Filter.notEqual
The 'notEqual' filter gets the objects where the given key does not have the specified value. The `notEqual` filter gets the objects where the given key does not have the specified value.
```dart ```dart
Filter.notEqual('type', 'messaging'), Filter.notEqual('type', 'messaging'),
@@ -64,20 +64,20 @@ Filter.lessOrEqual('count', 5),
#### Filter.in_ #### Filter.in_
The 'in_' filter allows getting objects where the key matches any in a specified array. The `in_` filter allows getting objects where the key matches any in a specified array.
```dart ```dart
Filter.in_('members', [user.id]) Filter.in_('members', [user.id])
``` ```
:::note :::note
Since 'in' is a keyword in Dart, the filter has an underscore added. This does not apply to the 'notIn' Since `in` is a keyword in Dart, the filter has an underscore added. This does not apply to the `notIn`
keyword. keyword.
::: :::
#### Filter.notIn #### Filter.notIn
The 'notIn' filter allows getting objects where the key matches none in a specified array. The `notIn` filter allows getting objects where the key matches none in a specified array.
```dart ```dart
Filter.notIn('members', [user.id]) Filter.notIn('members', [user.id])
@@ -109,7 +109,7 @@ Filter.exists('name')
#### Filter.notExists #### Filter.notExists
The 'notExists' filter checks if the specified key doesn't exist. This is a simplified call to `Filter.exists` The `notExists` filter checks if the specified key doesn't exist. This is a simplified call to `Filter.exists`
with the value set to false. with the value set to false.
```dart ```dart
@@ -155,7 +155,7 @@ Running the above will give this:
![](../assets/authentication_demo_app.jpg) ![](../assets/authentication_demo_app.jpg)
The `Auth` widget handles all of the authentication logic. It initializes a `FirebaseAuth.instance` and uses that The `Auth` widget handles all of the authentication logic. It initializes a `FirebaseAuth.instance` and uses that
in the `createAccount`, `signIn` and `signOut` methods. There is a button to envoke each of these methods. in the `createAccount`, `signIn` and `signOut` methods. There is a button to invoke each of these methods.
The `FirebaseFunctions.instance` will be used later in this guide. The `FirebaseFunctions.instance` will be used later in this guide.
@@ -289,7 +289,7 @@ firebase deploy --only functions
### Create a Stream User and Get the User's Token ### Create a Stream User and Get the User's Token
In the `createStreamUserAndGetToken` cloud function you create an `onCall` HTTPS handler, which exposes In the `createStreamUserAndGetToken` cloud function you create an `onCall` HTTPS handler, which exposes
a cloud function that can be envoked from your Flutter app. a cloud function that can be invoked from your Flutter app.
```js ```js
// Create a Stream user and return auth token. // Create a Stream user and return auth token.
@@ -325,13 +325,13 @@ by ensuring that `context.auth` is not null. If it is null, then it throws an `H
message. This error can be caught in your Flutter application. message. This error can be caught in your Flutter application.
If the caller is authenticated the function proceeds to use the `serverClient` to create a new Stream Chat If the caller is authenticated the function proceeds to use the `serverClient` to create a new Stream Chat
user by calling the `upsertUser` method and passing in some user data. It uses the authenticated caller's **uid** as an **id**. user by calling the `upsertUser` method and passing in some user data. It uses the authenticated caller's **`uid`** as an **id**.
After the user is created it generates a token for that user. This token is then returned to the caller. After the user is created it generates a token for that user. This token is then returned to the caller.
To call this from Flutter, you will need to use the `cloud_functions` package. To call this from Flutter, you will need to use the `cloud_functions` package.
Update the **createAccount** method in your Flutter code to the following: Update the **`createAccount`** method in your Flutter code to the following:
```dart ```dart
Future<void> createAccount() async { Future<void> createAccount() async {
@@ -355,7 +355,7 @@ in the request.
Once you have the Stream user token, you can authenticate your Stream Chat user as you normally would. Once you have the Stream user token, you can authenticate your Stream Chat user as you normally would.
Please see our [initialization documention](https://getstream.io/chat/docs/flutter-dart/init_and_users/?language=dart) for more information. Please see our [initialization documentation](https://getstream.io/chat/docs/flutter-dart/init_and_users/?language=dart) for more information.
As you can see below, the User ID matches on both Firebase's and Stream's user database. As you can see below, the User ID matches on both Firebase's and Stream's user database.
@@ -373,7 +373,7 @@ As you can see below, the User ID matches on both Firebase's and Stream's user d
The `getStreamUserToken` cloud function is very similar to the `createStreamUserAndGetToken` function. The only difference is The `getStreamUserToken` cloud function is very similar to the `createStreamUserAndGetToken` function. The only difference is
that it only creates a user token and does not create a new user account on Stream. that it only creates a user token and does not create a new user account on Stream.
Update the **signIn** method in your Flutter code to the following: Update the **`signIn`** method in your Flutter code to the following:
```dart ```dart
Future<void> signIn() async { Future<void> signIn() async {
@@ -434,7 +434,7 @@ exports.deleteStreamUser = functions.auth.user().onDelete((user, context) => {
``` ```
In this function, you are listening to delete events on Firebase auth. When an account is deleted, this function will be triggered, and you can get the In this function, you are listening to delete events on Firebase auth. When an account is deleted, this function will be triggered, and you can get the
user's **uid** and call the `deleteUser` method on the `serverClient`. user's **`uid`** and call the `deleteUser` method on the `serverClient`.
This is not an external cloud function; it can only be triggered when an This is not an external cloud function; it can only be triggered when an
account is deleted. account is deleted.
@@ -41,8 +41,8 @@ which will be addressed by the respective plugin creators over time.
The library uses [flutter file picker plugin](https://github.com/miguelpruivo/flutter_file_picker) to pick files from the os. The library uses [flutter file picker plugin](https://github.com/miguelpruivo/flutter_file_picker) to pick files from the os.
Follow [this wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#ios) to fulfill iOS requirements. Follow [this wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#ios) to fulfill iOS requirements.
We also use [video_player](https://pub.dev/packages/video_player) to reproduce videos. We also use [`video_player`](https://pub.dev/packages/video_player) to reproduce videos.
Follow [this guide](https://pub.dev/packages/video_player#installation) to fulfill the requirements. Follow [this guide](https://pub.dev/packages/video_player#installation) to fulfill the requirements.
To pick images from the camera, we use the [image_picker](https://pub.dev/packages/image_picker) plugin. To pick images from the camera, we use the [`image_picker`](https://pub.dev/packages/image_picker) plugin.
Follow [these instructions](https://pub.dev/packages/image_picker#ios) to check the requirements. Follow [these instructions](https://pub.dev/packages/image_picker#ios) to check the requirements.
@@ -90,7 +90,7 @@ StreamChannelListHeader(
![](../assets/channel_list_header_custom_subtitle.png) ![](../assets/channel_list_header_custom_subtitle.png)
The `titleBuilder` param helps you build different titles depending on the connection state: The `titleBuilder` parameter helps you build different titles depending on the connection state:
```dart ```dart
//... //...
@@ -15,7 +15,7 @@ according to the filters and sort order given. However, in some cases, implement
that cannot be done using the customization approaches given in the widget. 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 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 fetches channels in the expected way via the usual parameters 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. exposes builders to build the UI in situations such as loading, empty data, errors, and on data received.
### Basic Example ### Basic Example
@@ -11,7 +11,7 @@ Find the pub.dev documentation [here](https://pub.dev/documentation/stream_chat_
`StreamChatCore` is used to provide information about the chat client to the widget tree. `StreamChatCore` is used to provide information about the chat client to the widget tree.
This Widget is used to react to life cycle changes and system updates. This Widget is used to react to life cycle changes and system updates.
When the app goes into the background, the websocket connection is automatically closed and when it goes back to foreground the connection is opened again. When the app goes into the background, the web socket connection is automatically closed and when it goes back to foreground the connection is opened again.
Like the `StreamChat` widget in the higher level UI package, the `StreamChatCore` widget should Like the `StreamChat` widget in the higher level UI package, the `StreamChatCore` widget should
be on the top level before using any Stream functionality: be on the top level before using any Stream functionality:
+1 -1
View File
@@ -50,7 +50,7 @@ pubspec.lock
# If you don't generate documentation locally you can remove this line. # If you don't generate documentation locally you can remove this line.
doc/api/ doc/api/
# Avoid committing generated Javascript files: # Avoid committing generated JavaScript files:
*.dart.js *.dart.js
*.info.json # Produced by the --dump-info flag. *.info.json # Produced by the --dump-info flag.
*.js # When generated by dart2js. Don't specify *.js if your *.js # When generated by dart2js. Don't specify *.js if your
+13 -13
View File
@@ -17,7 +17,7 @@
🛑️ Breaking Changes from `5.0.0-beta.2` 🛑️ Breaking Changes from `5.0.0-beta.2`
- `Channel.addMembers`, `Channel.removeMembers`, `Channel.inviteMembers` and `Channel.update` - `Channel.addMembers`, `Channel.removeMembers`, `Channel.inviteMembers` and `Channel.update`
positional params are now optional params. positional parameters are now optional parameters.
```dart ```dart
// previous // previous
@@ -390,21 +390,21 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
🛑️ Breaking Changes from `1.5.3` 🛑️ Breaking Changes from `1.5.3`
- migrate this package to null safety - migrate this package to null safety
- `ConnectUserWithProvider` now requires `tokenProvider` as a required param. (Removed from the - `ConnectUserWithProvider` now requires `tokenProvider` as a required parameter. (Removed from the
constructor) constructor)
- `client.disconnect()` is now divided into two different functions - `client.disconnect()` is now divided into two different functions
- `client.closeConnection()` -> for closing user websocket connection. - `client.closeConnection()` -> for closing user web socket connection.
- `client.disconnectUser()` -> for disconnecting user and resetting client state. - `client.disconnectUser()` -> for disconnecting user and resetting client state.
- `client.devToken()` now returns a `Token` model instead of `String`. - `client.devToken()` now returns a `Token` model instead of `String`.
- `ApiError` is removed in favor of `StreamChatError` - `ApiError` is removed in favor of `StreamChatError`
- `StreamChatError` -> parent type for all the stream errors. - `StreamChatError` -> parent type for all the stream errors.
- `StreamWebSocketError` -> for user websocket related errors. - `StreamWebSocketError` -> for user web socket related errors.
- `StreamChatNetworkError` -> for network related errors. - `StreamChatNetworkError` -> for network related errors.
- `client.queryChannels()`, `channel.query()` options param is removed in favor of individual params - `client.queryChannels()`, `channel.query()` options parameter is removed in favor of individual parameters
- `option.state` -> bool state - `option.state` -> bool state
- `option.watch` -> bool watch - `option.watch` -> bool watch
- `option.presence` -> bool presence - `option.presence` -> bool presence
- `client.queryUsers()` options param is removed in favor of individual params - `client.queryUsers()` options parameter is removed in favor of individual parameters
- `option.presence` -> bool presence - `option.presence` -> bool presence
- Migrate this package to null safety - Migrate this package to null safety
- Added typed filters - Added typed filters
@@ -438,28 +438,28 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
🛑️ Breaking Changes from `2.0.0-nullsafety.6` 🛑️ Breaking Changes from `2.0.0-nullsafety.6`
- `ConnectUserWithProvider` now requires `tokenProvider` as a required param. (Removed from the - `ConnectUserWithProvider` now requires `tokenProvider` as a required parameter. (Removed from the
constructor) constructor)
- `client.disconnect()` is now divided into two different functions - `client.disconnect()` is now divided into two different functions
- `client.closeConnection()` -> for closing user websocket connection. - `client.closeConnection()` -> for closing user web socket connection.
- `client.disconnectUser()` -> for disconnecting user and resetting client state. - `client.disconnectUser()` -> for disconnecting user and resetting client state.
- `client.devToken()` now returns a `Token` model instead of `String`. - `client.devToken()` now returns a `Token` model instead of `String`.
- `ApiError` is removed in favor of `StreamChatError` - `ApiError` is removed in favor of `StreamChatError`
- `StreamChatError` -> parent type for all the stream errors. - `StreamChatError` -> parent type for all the stream errors.
- `StreamWebSocketError` -> for user websocket related errors. - `StreamWebSocketError` -> for user web socket related errors.
- `StreamChatNetworkError` -> for network related errors. - `StreamChatNetworkError` -> for network related errors.
- `client.queryChannels()`, `channel.query()` options param is removed in favor of individual params - `client.queryChannels()`, `channel.query()` options parameter is removed in favor of individual parameters
- `option.state` -> bool state - `option.state` -> bool state
- `option.watch` -> bool watch - `option.watch` -> bool watch
- `option.presence` -> bool presence - `option.presence` -> bool presence
- `client.queryUsers()` options param is removed in favor of individual params - `client.queryUsers()` options parameter is removed in favor of individual parameters
- `option.presence` -> bool presence - `option.presence` -> bool presence
✅ Added ✅ Added
- New `Location` enum is introduced for easily changing the client location/baseUrl. - New `Location` enum is introduced for easily changing the client location/baseUrl.
- New `client.openConnection()` and `client.closeConnection()` is introduced to connect/disconnect - New `client.openConnection()` and `client.closeConnection()` is introduced to connect/disconnect
user ws connection. user WS connection.
🔄 Changed 🔄 Changed
@@ -562,7 +562,7 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
- 🛑 **BREAKING** Renamed `Client` to less generic `StreamChatClient` - 🛑 **BREAKING** Renamed `Client` to less generic `StreamChatClient`
- 🛑 **BREAKING** Segregated the persistence layer into separate - 🛑 **BREAKING** Segregated the persistence layer into separate
package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) package [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence)
- 🛑 **BREAKING** Moved `Client.backgroundKeepAlive` - 🛑 **BREAKING** Moved `Client.backgroundKeepAlive`
to [core package](https://pub.dev/packages/stream_chat_core) to [core package](https://pub.dev/packages/stream_chat_core)
- 🛑 **BREAKING** Moved `Client.showLocalNotification` - 🛑 **BREAKING** Moved `Client.showLocalNotification`
+6 -6
View File
@@ -39,7 +39,7 @@ There is a detailed Flutter example project in the `example` folder. You can dir
## Setup API Client ## Setup API Client
First you need to instantiate a chat client. The Chat client will manage API call, event handling and manage the websocket connection to Stream Chat servers. You should only create the client once and re-use it across your application. First you need to instantiate a chat client. The Chat client will manage API call, event handling and manage the web socket connection to Stream Chat servers. You should only create the client once and re-use it across your application.
```dart ```dart
final client = StreamChatClient("stream-chat-api-key"); final client = StreamChatClient("stream-chat-api-key");
@@ -47,7 +47,7 @@ final client = StreamChatClient("stream-chat-api-key");
### Logging ### Logging
By default the Chat Client will write all messages with level Warn or Error to stdout. By default the Chat Client will write all messages with level Warn or Error to `stdout`.
#### Change Logging Level #### Change Logging Level
@@ -59,7 +59,7 @@ final client = StreamChatClient("stream-chat-api-key", logLevel: Level.INFO);
#### Custom Logger #### Custom Logger
You can handle the log messages directly instead of have them written to stdout, this is very convenient if you use an error tracking tool or if you want to centralize your logs into one facility. You can handle the log messages directly instead of have them written to `stdout`, this is very convenient if you use an error tracking tool or if you want to centralize your logs into one facility.
```dart ```dart
myLogHandlerFunction = (LogRecord record) { myLogHandlerFunction = (LogRecord record) {
@@ -71,7 +71,7 @@ final client = StreamChatClient("stream-chat-api-key", logHandlerFunction: myLog
### Offline storage ### Offline storage
To add data persistance you can extend the class `ChatPersistenceClient` and pass an instance to the `StreamChatClient`. To add data persistence, you can extend the class `ChatPersistenceClient` and pass an instance to the `StreamChatClient`.
```dart ```dart
class CustomChatPersistentClient extends ChatPersistenceClient { class CustomChatPersistentClient extends ChatPersistenceClient {
@@ -84,7 +84,7 @@ final client = StreamChatClient(
)..chatPersistenceClient = CustomChatPersistentClient(); )..chatPersistenceClient = CustomChatPersistentClient();
``` ```
We provide an official persistent client in the [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence) package. We provide an official persistent client in the [`stream_chat_persistence`](https://pub.dev/packages/stream_chat_persistence) package.
```dart ```dart
import 'package:stream_chat_persistence/stream_chat_persistence.dart'; import 'package:stream_chat_persistence/stream_chat_persistence.dart';
@@ -104,7 +104,7 @@ final client = StreamChatClient(
### Code conventions ### Code conventions
- Make sure that you run `dartfmt` before commiting your code - Make sure that you run `dartfmt` before you commit your code
- Make sure all public methods and functions are well documented - Make sure all public methods and functions are well documented
### Running tests ### Running tests
+1 -1
View File
@@ -50,7 +50,7 @@ pubspec.lock
# If you don't generate documentation locally you can remove this line. # If you don't generate documentation locally you can remove this line.
doc/api/ doc/api/
# Avoid committing generated Javascript files: # Avoid committing generated JavaScript files:
*.dart.js *.dart.js
*.info.json # Produced by the --dump-info flag. *.info.json # Produced by the --dump-info flag.
*.js # When generated by dart2js. Don't specify *.js if your *.js # When generated by dart2js. Don't specify *.js if your
+8 -8
View File
@@ -1,4 +1,4 @@
## Upcomming ## Upcoming
🔄 Changed 🔄 Changed
@@ -43,7 +43,7 @@
✅ Added ✅ Added
- Added `StreamMemberGridView` and `StreamMemberListView`. - Added `StreamMemberGridView` and `StreamMemberListView`.
- Added support for additional text field params in `StreamMessageInput` - Added support for additional text field parameters in `StreamMessageInput`
* `maxLines` * `maxLines`
* `minLines` * `minLines`
* `textInputAction` * `textInputAction`
@@ -228,7 +228,7 @@
- Fix commands resetting the `StreamMessageInputController.value`. - Fix commands resetting the `StreamMessageInputController.value`.
- [[#996]](https://github.com/GetStream/stream-chat-flutter/issues/996) Videos break bottom photo - [[#996]](https://github.com/GetStream/stream-chat-flutter/issues/996) Videos break bottom photo
carousal. carousal.
- Fix: URLs with path and/or query params are not enriched. - Fix: URLs with path and/or query parameters are not enriched.
- [[#1194]](https://github.com/GetStream/stream-chat-flutter/issues/1194) Request permission to - [[#1194]](https://github.com/GetStream/stream-chat-flutter/issues/1194) Request permission to
access gallery when opening the file picker. access gallery when opening the file picker.
@@ -892,11 +892,11 @@ typedef MessageBuilder = Widget Function(
## 1.0.0-beta ## 1.0.0-beta
- **Refreshed widgets design** - **Refreshed widgets design**
- Improved api documentation - Improved API documentation
- Updated `stream_chat` dependency to `^1.0.0-beta` - Updated `stream_chat` dependency to `^1.0.0-beta`
- Extracted sample app into dedicated [repo](https://github.com/GetStream/flutter-samples) - Extracted sample app into dedicated [repository](https://github.com/GetStream/flutter-samples)
- Reimplemented existing widgets - Re-implemented existing widgets
using [stream_chat_flutter_core](https://pub.dev/packages/stream_chat_flutter_core) using [`stream_chat_flutter_core`](https://pub.dev/packages/stream_chat_flutter_core)
## 0.2.21 ## 0.2.21
@@ -905,7 +905,7 @@ typedef MessageBuilder = Widget Function(
## 0.2.20+4 ## 0.2.20+4
- Fix channelPreview when the message list is empty - Fix `channelPreview` when the message list is empty
## 0.2.20+3 ## 0.2.20+3
+9 -9
View File
@@ -32,7 +32,7 @@ It teaches you how to use this SDK and also shows how to make frequently require
## Example App ## Example App
This repo includes a fully functional example app with setup instructions. This repository includes a fully functional example app with setup instructions.
The example is available under the [example](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_flutter/example) folder. The example is available under the [example](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_flutter/example) folder.
## Add dependency ## Add dependency
@@ -46,7 +46,7 @@ You should then run `flutter packages get`
### Android ### Android
The package uses [photo_manager](https://pub.dev/packages/photo_manager) to access the device's photo library. The package uses [`photo_manager`](https://pub.dev/packages/photo_manager) to access the device's photo library.
Follow [this wiki](https://pub.dev/packages/photo_manager#android-10-q-29) to fulfil the Android requirements. Follow [this wiki](https://pub.dev/packages/photo_manager#android-10-q-29) to fulfil the Android requirements.
### iOS ### iOS
@@ -55,9 +55,9 @@ The library uses [flutter file picker plugin](https://github.com/miguelpruivo/fl
files from the os. files from the os.
Follow [this wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#ios) to fulfill iOS requirements. Follow [this wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#ios) to fulfill iOS requirements.
We also use [video_player](https://pub.dev/packages/video_player) to reproduce videos. Follow [this guide](https://pub.dev/packages/video_player#installation) to fulfill the requirements. We also use [`video_player`](https://pub.dev/packages/video_player) to reproduce videos. Follow [this guide](https://pub.dev/packages/video_player#installation) to fulfill the requirements.
To pick images from the camera, we use the [image_picker](https://pub.dev/packages/image_picker) plugin. To pick images from the camera, we use the [`image_picker`](https://pub.dev/packages/image_picker) plugin.
Follow [these instructions](https://pub.dev/packages/image_picker#ios) to check the requirements. Follow [these instructions](https://pub.dev/packages/image_picker#ios) to check the requirements.
### Web ### Web
@@ -70,7 +70,7 @@ For the web, edit your `index.html` and add the following in the `<body>` tag in
### MacOS ### MacOS
For MacOS use the [file_selector](https://pub.dev/packages/file_selector#macos) package. For MacOS use the [`file_selector`](https://pub.dev/packages/file_selector#macos) package.
Follow [these instructions](https://pub.dev/packages/file_selector#macos) to check the requirements. Follow [these instructions](https://pub.dev/packages/file_selector#macos) to check the requirements.
You also need to add the following [entitlement](https://docs.flutter.dev/development/platform-integration/desktop#entitlements-and-the-app-sandbox): You also need to add the following [entitlement](https://docs.flutter.dev/development/platform-integration/desktop#entitlements-and-the-app-sandbox):
@@ -88,8 +88,8 @@ If it seems related to the [flutter file picker plugin](https://github.com/migue
## Docs ## Docs
This package provides UI components required for integrating Stream Chat into your application. This package provides UI components required for integrating Stream Chat into your application.
Alternatively, you may use the core package [stream_chat_flutter_core](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_flutter_core) which allows more customisation and provides business logic but no UI components. Alternatively, you may use the core package [`stream_chat_flutter_core`](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat_flutter_core) which allows more customisation and provides business logic but no UI components.
If you require the maximum amount of control over the API, please use the low level client package: [stream_chat](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat). If you require the maximum amount of control over the API, please use the low level client package: [`stream_chat`](https://github.com/GetStream/stream-chat-flutter/tree/master/packages/stream_chat).
### UI Components ### UI Components
@@ -175,7 +175,7 @@ Out of the box, all chat widgets use their default styling, and there are two wa
### Offline storage ### Offline storage
To add data persistance you can extend the class `ChatPersistenceClient` and pass an instance to the `StreamChatClient`. To add data persistence you can extend the class `ChatPersistenceClient` and pass an instance to the `StreamChatClient`.
```dart ```dart
class CustomChatPersistentClient extends ChatPersistenceClient { class CustomChatPersistentClient extends ChatPersistenceClient {
@@ -207,7 +207,7 @@ final client = StreamChatClient(
## Contributing ## Contributing
We welcome code changes that improve this library or fix a problem, We welcome code changes that improve this library or fix a problem,
please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on Github. please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on GitHub.
We are pleased to merge your code into the official repository. We are pleased to merge your code into the official repository.
Make sure to sign our [Contributor License Agreement (CLA)](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) first. Make sure to sign our [Contributor License Agreement (CLA)](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) first.
See our license file for more details. See our license file for more details.
@@ -21,7 +21,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart';
/// ///
/// - We set up the Chat [StreamChatClient] with the API key /// - We set up the Chat [StreamChatClient] with the API key
/// ///
/// - We set the the current user for Chat with [StreamChatClient.connectUser] /// - We set the current user for Chat with [StreamChatClient.connectUser]
/// and a pre-generated user token /// and a pre-generated user token
/// ///
/// - We make [StreamChat] the root Widget of our application /// - We make [StreamChat] the root Widget of our application