diff --git a/.github/workflows/flutter-analyze.yml b/.github/workflows/flutter-analyze.yml deleted file mode 100644 index 312a65ba..00000000 --- a/.github/workflows/flutter-analyze.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Flutter Analyze -on: - push: - branches: - - master - - pull_request: - branches: - - '*' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: subosito/flutter-action@v1 - with: - channel: 'beta' - - run: flutter pub get - - - name: 'Flutter Format Check' - run: flutter format --set-exit-if-changed --dry-run . - - - run: flutter analyze diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index bb72c2f2..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: CI - -on: - push: - branches: - - master - pull_request: - release: - types: - - created - -jobs: - test: - runs-on: [ubuntu-latest] - steps: - - uses: actions/checkout@v2 - - name: Flutter action - uses: subosito/flutter-action@v1.4.0 - with: - channel: 'stable' - - name: Get dependencies - run: flutter pub get - - name: Coverage fix - run: | - file=test/coverage_helper_test.dart - echo "// Helper file to make coverage work for all dart files\n" > $file - echo "// ignore_for_file: unused_import" >> $file - find lib -name '*.dart' | grep -e '[^g]\.dart' | grep -v '_html.dart' | cut -c4- | awk -v package=stream_chat_flutter '{printf "import '\''package:%s%s'\'';\n", package, $1}' >> $file - echo "" >> $file - echo "void main(){}" >> $file - cat $file - - name: Run tests - run: flutter test --coverage - - name: Codecov - run: bash <(curl -s https://codecov.io/bash) -c -t ${{ secrets.CODECOV_TOKEN }} -f coverage/lcov.info -F flutter_tool diff --git a/.github/workflows/scripts/install-flutter.sh b/.github/workflows/scripts/install-flutter.sh new file mode 100755 index 00000000..247d2797 --- /dev/null +++ b/.github/workflows/scripts/install-flutter.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +BRANCH=$1 + +if [ "$BRANCH" == "dev" ] +then + # TODO Flutter dev branch is currently broken so we're unable to test MacOS. + echo "TODO: Skipping macOS testing due to Flutter dev branch issue. Switching branch to stable." + BRANCH=stable +fi + +git clone https://github.com/flutter/flutter.git --depth 1 -b $BRANCH _flutter +echo "::add-path::$GITHUB_WORKSPACE/_flutter/bin" \ No newline at end of file diff --git a/.github/workflows/scripts/install-tools.sh b/.github/workflows/scripts/install-tools.sh new file mode 100755 index 00000000..1f77f519 --- /dev/null +++ b/.github/workflows/scripts/install-tools.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +flutter pub global activate melos 0.4.0+1 +echo "::add-path::$HOME/.pub-cache/bin" +echo "::add-path::$GITHUB_WORKSPACE/_flutter/.pub-cache/bin" +echo "::add-path::$GITHUB_WORKSPACE/_flutter/bin/cache/dart-sdk/bin" \ No newline at end of file diff --git a/.github/workflows/scripts/validate-formatting.sh b/.github/workflows/scripts/validate-formatting.sh new file mode 100755 index 00000000..27e33215 --- /dev/null +++ b/.github/workflows/scripts/validate-formatting.sh @@ -0,0 +1,30 @@ +#!/bin/bash +if [[ $(git ls-files --modified) ]]; then + echo "" + echo "" + echo "These files are not formatted correctly:" + for f in $(git ls-files --modified); do + echo "" + echo "" + echo "-----------------------------------------------------------------" + echo "$f" + echo "-----------------------------------------------------------------" + echo "" + git --no-pager diff --unified=0 --minimal $f + echo "" + echo "-----------------------------------------------------------------" + echo "" + echo "" + done + if [[ $GITHUB_WORKFLOW ]]; then + git checkout . > /dev/null 2>&1 + fi + echo "" + echo "❌ Some files are incorrectly formatted, see above output." + echo "" + echo "To fix these locally, run: 'melos run format'." + exit 1 +else + echo "" + echo "✅ All files are formatted correctly." +fi \ No newline at end of file diff --git a/.github/workflows/stream_flutter_workflow.yml b/.github/workflows/stream_flutter_workflow.yml new file mode 100644 index 00000000..4c8882d7 --- /dev/null +++ b/.github/workflows/stream_flutter_workflow.yml @@ -0,0 +1,103 @@ +name: stream_flutter_workflow + +env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + +on: + pull_request: + push: + branches: + - master + paths-ignore: + - 'docs/**' + +jobs: + analyze: + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 0 + - name: 'Install Flutter' + run: ./.github/workflows/scripts/install-flutter.sh stable + - name: 'Install Tools' + run: | + ./.github/workflows/scripts/install-tools.sh + flutter pub global activate tuneup + - name: 'Bootstrap Workspace' + run: melos bootstrap + - name: 'Dart Analyze' + run: | + melos exec -c 3 -- \ + tuneup check + - name: 'Pub Check' + run: | + melos exec -c 1 --no-private --ignore="*example*" -- \ + pub publish --dry-run + format: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 0 + - name: 'Install Flutter' + run: ./.github/workflows/scripts/install-flutter.sh stable + - name: 'Install Tools' + run: | + ./.github/workflows/scripts/install-tools.sh + curl -sL https://github.com/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar -o $HOME/google-java-format.jar + - name: 'Bootstrap Workspace' + run: melos bootstrap + - name: 'Dart' + run: | + melos exec -c 1 -- \ + flutter format . + ./.github/workflows/scripts/validate-formatting.sh + - name: 'Objective-C' + if: ${{ success() || failure() }} + run: | + melos exec -c 4 --ignore="*platform_interface*" --ignore="*web*" -- \ + find . -maxdepth 3 -name "*.h" -o -name "*.m" -print0 \| xargs -0 clang-format -i --style=Google --verbose + ./.github/workflows/scripts/validate-formatting.sh + - name: 'Java' + if: ${{ success() || failure() }} + run: | + melos exec -c 4 --ignore="*platform_interface*" --ignore="*web*" -- \ + find . -maxdepth 12 -name "*.java" -print0 \| xargs -0 java -jar $HOME/google-java-format.jar --replace + ./.github/workflows/scripts/validate-formatting.sh + + test_dart: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 0 + - name: 'Install Flutter' + run: ./.github/workflows/scripts/install-flutter.sh stable + - name: 'Install Tools' + run: ./.github/workflows/scripts/install-tools.sh + - name: 'Bootstrap Workspace' + run: melos bootstrap + - name: 'Flutter Test' + run: cd packages/stream_chat && flutter pub run test + + test_flutter: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 0 + - name: 'Install Flutter' + run: ./.github/workflows/scripts/install-flutter.sh stable + - name: 'Install Tools' + run: ./.github/workflows/scripts/install-tools.sh + - name: 'Bootstrap Workspace' + run: melos bootstrap + - name: 'Flutter Test' + run: | + melos exec -c 3 --flutter --dir-exists=test --ignore="*example*" --ignore="*web*" -- \ + flutter test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3a158cd4..f7a23bbb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,64 +1,53 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp .DS_Store .atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws .idea/ +.vscode/ -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies .packages -.pub-cache/ .pub/ -/build/ -coverage/ -coverage_helper_test.dart - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages -# See https://www.dartlang.org/guides/libraries/private-files - -# Files and directories created by pub .dart_tool/ -.packages -build/ -# If you're building an application, you may want to check-in your pubspec.lock pubspec.lock +flutter_export_environment.sh -# Directory created by dartdoc -# If you don't generate documentation locally you can remove this line. -doc/api/ +examples/all_plugins/pubspec.yaml -# Avoid committing generated Javascript files: -*.dart.js -*.info.json # Produced by the --dump-info flag. -*.js # When generated by dart2js. Don't specify *.js if your - # project includes source files written in JavaScript. -*.js_ -*.js.deps -*.js.map +Podfile +Podfile.lock +Pods/ +.symlinks/ +**/Flutter/App.framework/ +**/Flutter/ephemeral/ +**/Flutter/Flutter.framework/ +**/Flutter/Generated.xcconfig +**/Flutter/flutter_assets/ -fvm -google-services.json -example/ios/dist \ No newline at end of file +ServiceDefinitions.json +xcuserdata/ +**/DerivedData/ + +local.properties +keystore.properties +.gradle/ +gradlew +gradlew.bat +gradle-wrapper.jar +.flutter-plugins-dependencies +*.iml + +generated_plugin_registrant.dart +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m +GeneratedPluginRegistrant.java +GeneratedPluginRegistrant.swift +build/ +.flutter-plugins + +.project +.classpath +.settings +/.fvm + +.melos_tool/ +/packages/flutter_widgets/example/ios/Flutter/.last_build_id +/packages/dart_client/example/ios/Flutter/.last_build_id +/packages/dart_client/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/README.md b/README.md index c5e4c9e7..816e96a1 100644 --- a/README.md +++ b/README.md @@ -1,169 +1,59 @@ -# Official Flutter SDK for [Stream Chat](https://getstream.io/chat/) +# Stream Chat Dart -
+ -> The official Flutter components for Stream Chat, a service for -> building chat applications. +This repository contains code for our [Dart](https://dart.dev/) and [Flutter](https://flutter.dev/) chat clients. -[](https://pub.dartlang.org/packages/stream_chat_flutter) - -[](https://gitter.im/GetStream/stream-chat-flutter?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) - -
+Stream allows developers to rapidly deploy scalable feeds and chat messaging with an industry leading 99.999% uptime SLA guarantee.
-**Quick Links**
+## Structure
+Stream Chat Dart is a monorepo built using [Melos](https://docs.page/invertase/melos). Individual packages can be found in the `packages` directory while configuration and top level commands can be found in `melos.yaml`.
-- [Register](https://getstream.io/chat/trial/) to get an API key for Stream Chat
-- [Flutter Chat Tutorial](https://getstream.io/chat/flutter/tutorial/)
-- [Chat UI Kit](https://getstream.io/chat/ui-kit/)
+To get started, run `bootstrap` after cloning the project.
-## Flutter Chat Tutorial
-
-The best place to start is the [Flutter Chat Tutorial](https://getstream.io/chat/flutter/tutorial/).
-It teaches you how to use this SDK and also shows how to make frequently required changes.
-
-## Example App
-
-This repo 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/example) folder.
-
-## Add dependency
-Add this to your package's pubspec.yaml file, use the latest version [](https://pub.dartlang.org/packages/stream_chat_flutter)
-```yaml
-dependencies:
- stream_chat_flutter: ^latest_version
+```shell
+melos bootstrap
```
-You should then run `flutter packages get`
+## Available Commands
+### Analyze
+> Requires `tuneup` to be activated globally. Please see https://pub.dev/packages/tuneup
+```shell
+melos run analyze
+```
-### Android
+### Pub Lint
+Runs pub publish with ``--dry-run``
+```shell
+melos run lint:pub
+```
-All set ✅
+### Build iOS
+Builds iOS examples without codesign
+```shell
+melos run build:examples:ios
+```
-### iOS
+### Build APK
+Builds an Android APK for examples
+```shell
+melos run build:examples:android
+```
-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.
+### Build MACOS
+Builds MacOs for all examples
+```shell
+melos run build:examples:macos
+```
-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.
+### Test
+Runs `flutter test` on all packages
+```shell
+melos run test
+```
-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.
-
-### Troubleshooting
-
-It may happen that you have some problems building the app.
-If it seems related to the [flutter file picker plugin](https://github.com/miguelpruivo/flutter_file_picker) make sure to check [this page](https://github.com/miguelpruivo/flutter_file_picker/wiki/Troubleshooting)
-
-## Docs
-
-### Business logic components
-
-We provide 3 Widgets dedicated to business logic and state management:
-
-- [StreamChat](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChat-class.html)
-- [StreamChannel](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChannel-class.html)
-- [ChannelsBloc](https://pub.dev/documentation/stream_chat_flutter/0.2.0-alpha+2/stream_chat_flutter/ChannelsBloc-class.html)
-
-### UI Components
-
-These are the available Widgets that you can use to build your application UI.
-Every widget uses the `StreamChat` or `StreamChannel` widgets to manage the state and communicate with Stream services.
-
-- [ChannelHeader](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ChannelHeader-class.html)
-- [ChannelImage](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ChannelImage-class.html)
-- [ChannelListView](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ChannelListView-class.html)
-- [ChannelName](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ChannelName-class.html)
-- [ChannelPreview](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ChannelPreview-class.html)
-- [MessageInput](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/MessageInput-class.html)
-- [MessageListView](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/MessageListView-class.html)
-- [MessageWidget](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/MessageWidget-class.html)
-- [StreamChatTheme](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChatTheme-class.html)
-- [ThreadHeader](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ThreadHeader-class.html)
-- ...
-
-### Customizing styles
-
-The Flutter SDK comes with a fully designed set of widgets that you can customize to fit with your application style and typography.
-Changing the theme of Chat widgets works in a very similar way that `MaterialApp` and `Theme` do.
-
-Out of the box, all chat widgets use their default styling, and there are two ways to change the styling:
-
- 1. Initialize the `StreamChatTheme` from your existing `MaterialApp` style
- ```dart
- class MyApp extends StatelessWidget {
- final Client client;
-
- MyApp(this.client);
-
- @override
- Widget build(BuildContext context) {
- final theme = ThemeData(
- primarySwatch: Colors.green,
- );
-
- return MaterialApp(
- theme: theme,
- builder: (context, child) => StreamChat(
- child: child,
- client: client,
- streamChatThemeData: StreamChatThemeData.fromTheme(theme),
- ),
- home: ChannelListPage(),
- );
- }
- }
- ```
-
- 2. Construct a custom theme and provide all the customizations needed
- ```dart
- class MyApp extends StatelessWidget {
- final Client client;
-
- MyApp(this.client);
-
- @override
- Widget build(BuildContext context) {
- final theme = ThemeData(
- primarySwatch: Colors.green,
- );
-
- return MaterialApp(
- theme: theme,
- builder: (context, child) => StreamChat(
- child: child,
- client: client,
- streamChatThemeData: StreamChatThemeData.fromTheme(theme).copyWith(
- ownMessageTheme: MessageTheme(
- messageBackgroundColor: Colors.black,
- messageText: TextStyle(
- color: Colors.white,
- ),
- avatarTheme: AvatarTheme(
- borderRadius: BorderRadius.circular(8),
- ),
- ),
- ),
- ),
- home: ChannelListPage(),
- );
- }
- }
- ```
-
-### Offline storage
-
-By default the library saves information about channels and messages in a SQLite DB.
-
-Set the property `persistenceEnabled` to false if you don't want to use the offline storage.
-
-## Contributing
-
-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.
-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.
-See our license file for more details.
+### Test Web
+Runs `flutter test --platform=chrome` on all packages
+```shell
+melos run test:web
+```
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 3723c0af..3ba5d599 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,61 +1,13 @@
-include: package:pedantic/analysis_options.yaml
+include: package:pedantic/analysis_options.1.9.0.yaml
analyzer:
exclude:
- - lib/**/*.g.dart
- - example/**
+ # Ignore generated files
+ - '**/*.g.dart'
+ - 'lib/src/generated/*.dart'
linter:
rules:
- # these rules are documented on and in the same order as
- # the Dart Lint rules page to make maintenance easier
- # https://github.com/dart-lang/linter/blob/master/example/all.yaml
- # - always_declare_return_types
- # - always_specify_types
- # - annotate_overrides
- # - avoid_as
- - avoid_empty_else
- - avoid_init_to_null
- - avoid_return_types_on_setters
- - avoid_web_libraries_in_flutter
- - await_only_futures
- - camel_case_types
- - cancel_subscriptions
- - close_sinks
- # - comment_references # we do not presume as to what people want to reference in their dartdocs
- # - constant_identifier_names # https://github.com/dart-lang/linter/issues/204
- - control_flow_in_finally
- - empty_constructor_bodies
- - empty_statements
- - hash_and_equals
- - implementation_imports
- # - invariant_booleans
- # - iterable_contains_unrelated_type
- - library_names
- # - library_prefixes
- # - list_remove_unrelated_type
- # - literal_only_boolean_expressions
- - non_constant_identifier_names
- # - one_member_abstracts
- # - only_throw_errors
- # - overridden_fields
-# - package_api_docs
- - package_names
- - package_prefixed_library_names
- - prefer_is_not_empty
- # - prefer_mixin # https://github.com/dart-lang/language/issues/32
- - public_member_api_docs
- - slash_for_doc_comments
- # - sort_constructors_first
- # - sort_unnamed_constructors_first
- # - super_goes_last # no longer needed w/ Dart 2
- - test_types_in_equals
- - throw_in_finally
- # - type_annotate_public_apis # subset of always_specify_types
- - type_init_formals
- # - unawaited_futures
- - unnecessary_brace_in_string_interps
- - unnecessary_getters_setters
- - unnecessary_statements
- - unrelated_type_equality_checks
- - valid_regexps
+ public_member_api_docs: true
+ prefer_final_in_for_each: true
+ prefer_final_locals: true
\ No newline at end of file
diff --git a/example/android/.gitignore b/example/android/.gitignore
deleted file mode 100644
index bc2100d8..00000000
--- a/example/android/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-gradle-wrapper.jar
-/.gradle
-/captures/
-/gradlew
-/gradlew.bat
-/local.properties
-GeneratedPluginRegistrant.java
diff --git a/example/android/app/src/main/kotlin/com/example/example/Application.kt b/example/android/app/src/main/kotlin/com/example/example/Application.kt
deleted file mode 100644
index dd47a03c..00000000
--- a/example/android/app/src/main/kotlin/com/example/example/Application.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.example.example
-
-import com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin
-import io.flutter.app.FlutterApplication
-import io.flutter.plugin.common.PluginRegistry
-import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
-import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin
-import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
-import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin
-import io.flutter.plugins.pathprovider.PathProviderPlugin
-
-class Application : FlutterApplication(), PluginRegistrantCallback {
- override fun onCreate() {
- super.onCreate()
- FlutterFirebaseMessagingService.setPluginRegistrant(this)
- }
-
- override fun registerWith(registry: PluginRegistry?) {
- PathProviderPlugin.registerWith(registry?.registrarFor(
- "io.flutter.plugins.pathprovider.PathProviderPlugin"))
- SharedPreferencesPlugin.registerWith(registry?.registrarFor(
- "io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin"))
- FlutterLocalNotificationsPlugin.registerWith(registry?.registrarFor(
- "com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
- FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
- }
-}
\ No newline at end of file
diff --git a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt
deleted file mode 100644
index 1656503f..00000000
--- a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.example.example
-
-import androidx.annotation.NonNull;
-import io.flutter.embedding.android.FlutterActivity
-import io.flutter.embedding.engine.FlutterEngine
-import io.flutter.plugins.GeneratedPluginRegistrant
-
-class MainActivity: FlutterActivity() {
- override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
- GeneratedPluginRegistrant.registerWith(flutterEngine);
- }
-}
diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml
deleted file mode 100644
index 00fa4417..00000000
--- a/example/android/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-