From 4488fa6c3aedd2d4b9c55aa16f69d8e641b0b036 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 9 Mar 2021 18:58:23 +0100 Subject: [PATCH] Release/1.4.0 beta (#318) * fix: fixed long system messages overflowing * fix: fixed long system messages overflowing * [UI-Kit] Refactor, add support for downloading attachments. Signed-off-by: Sahil Kumar * fix: header casing * [UI-Kit] Disable attachment download dialog pop using back button Signed-off-by: Sahil Kumar * stream_chat_flutter fix svg on web * [UI-Kit] Pop attachment download dialog in case of any error. Signed-off-by: Sahil Kumar * restore svg * feat: add pr title linter * fix test * fix client headers * update system message design * update gh token env var * add scopes * expose systemMessageBuilder in messagelistview * fix(ui): fix button size * add dispatch workflow * add dispatch workflow * update dispatch acton * add runson * fix ref * fix ref * update secret * specify repo * fix: list scroll keyboard behaviour (#304) * fix: Keyboard now closes by clicking on space or scrolling. * fix: Exposed system and normal message tap builders * fmt: dartfmt * feat: Add support for messages filter in `MessageListView` and `MessageListCore` (#303) * [MessageListView, MessageListCore] Add support for message filter Signed-off-by: Sahil Kumar * [UI-Kit -> Pubspec] Remove `stream_chat_flutter_core` relative import Signed-off-by: Sahil Kumar * add relative import * add relative import * remove svg for web * remove badge logic on web * style: Update for team lint (#297) * Update for team lint * fix tests * remove pedantic and sort deps * remove jiffy from system message Co-authored-by: Salvatore Giordano * add section highlighting sample app repo (#307) Co-authored-by: Salvatore Giordano * add null check to debounce * fix messagelistview loading errors * remove core relative import * fix: fixes message newline issue (#308) * fix: minor * fix: generate image thumbnails and use transparent image as placeholder for cached network images (#310) * update cdn handling * fix image attachment with new cdn * fix(ui): Fix message input permission request crash (#311) Signed-off-by: Sahil Kumar * fix(llc): update member presence and add skip_push to message (#314) * update member presence * add skip_push to message * fix tests * fix: Fixed shimmer overflow (#316) * fix dialogs * fix(llc): Fix attachment upload state uneven progress. (#315) * feat(llc): Add rate limiter functions. fix(llc): Fix attachment upload state uneven progress. Signed-off-by: Sahil Kumar * feat(llc): Export `async.dart` and `rate_limit.dart` Signed-off-by: Sahil Kumar * refactor(llc): Replace our `rate_limit` implementation with the dart port of js `lodash` to better handlw `cancel` and `flush` functions. Signed-off-by: Sahil Kumar * fix(UI-Kit): Make android example run on real devices Signed-off-by: Sahil Kumar * fix offline behaviour Co-authored-by: Salvatore Giordano * feat: Introduce onAttachmentTap on messages attachment (#309) * introdce onAttachmentTap on message * correct indent * sdfsd Co-authored-by: Salvatore Giordano * feat: added customization options in main widgets (#312) * polish channelpreview customization options * polish channelheader customization options * polish messageinput customization options * polish threadheader customization options * polish channellistheader customization options * show the parent message if no messages in thread * fix edit message * fix channelinfo textstyle * fix review * fix useravatar * add ontitle tap to thread header * add custom message actions * add borderradius and button builder * add ontap to messageinput custom send button * fix bottom sheet * add doc * use placeholder image * add doc * fix listtile density * remove subtitle from ChannelListHeaderTheme.copyWith * add InputDecoration.merge extension * fix: use shimmer in images * fix: remove notification badge logic from the sdk and move it to sample app * fix import * fix: Method being called during build (#317) * method call bug fix * dartfmt * fix: show error messages as system and keep them in the message input (#319) * fix: pre release (#324) * use share_plus plugin * bump dependency versions * fix ui for web * unfocus messageinput only on commands * fix default error for messagesearchlistview * fix thumbnail animation * fix lint * ignore example in linter * update changelogs * fix lint * fix lint * update stream_chat pana min * add doc Co-authored-by: Sahil Kumar Co-authored-by: Deven Joshi Co-authored-by: Neevash Ramdial (Nash) Co-authored-by: Nelson Nunes --- .github/workflows/dispatch_workflows.yml | 30 + .github/workflows/pana.yml | 2 +- .github/workflows/pr_title.yml | 22 + .github/workflows/stream_flutter_workflow.yml | 2 +- .gitignore | 2 +- README.md | 3 + packages/stream_chat/CHANGELOG.md | 7 + packages/stream_chat/analysis_options.yaml | 166 ++++-- packages/stream_chat/lib/src/api/channel.dart | 427 +++++++------ .../stream_chat/lib/src/api/requests.dart | 66 ++- .../stream_chat/lib/src/api/requests.g.dart | 2 +- .../stream_chat/lib/src/api/responses.dart | 15 +- .../stream_chat/lib/src/api/retry_policy.dart | 3 +- .../stream_chat/lib/src/api/retry_queue.dart | 14 +- .../stream_chat/lib/src/api/websocket.dart | 77 +-- .../lib/src/attachment_file_uploader.dart | 56 +- packages/stream_chat/lib/src/client.dart | 330 ++++++----- .../lib/src/db/chat_persistence_client.dart | 65 +- packages/stream_chat/lib/src/debounce.dart | 28 - packages/stream_chat/lib/src/exceptions.dart | 19 +- .../lib/src/extensions/map_extension.dart | 5 +- .../lib/src/extensions/rate_limit.dart | 335 +++++++++++ .../stream_chat/lib/src/models/action.dart | 12 +- .../lib/src/models/attachment.dart | 105 ++-- .../lib/src/models/attachment_file.dart | 20 +- .../lib/src/models/channel_config.dart | 52 +- .../lib/src/models/channel_model.dart | 66 +-- .../lib/src/models/channel_state.dart | 33 +- .../stream_chat/lib/src/models/command.dart | 18 +- .../stream_chat/lib/src/models/device.dart | 12 +- .../stream_chat/lib/src/models/event.dart | 96 ++- .../stream_chat/lib/src/models/member.dart | 52 +- .../stream_chat/lib/src/models/message.dart | 117 ++-- .../stream_chat/lib/src/models/message.g.dart | 2 + packages/stream_chat/lib/src/models/mute.dart | 17 +- .../stream_chat/lib/src/models/own_user.dart | 77 ++- .../stream_chat/lib/src/models/reaction.dart | 68 +-- packages/stream_chat/lib/src/models/read.dart | 21 +- .../lib/src/models/serialization.dart | 11 +- packages/stream_chat/lib/src/models/user.dart | 101 ++-- .../platform_detector/platform_detector.dart | 44 +- .../platform_detector_io.dart | 14 +- .../platform_detector_stub.dart | 2 +- .../platform_detector_web.dart | 4 +- packages/stream_chat/lib/stream_chat.dart | 6 +- packages/stream_chat/lib/version.dart | 3 +- packages/stream_chat/pubspec.yaml | 23 +- .../stream_chat/test/src/client_test.dart | 2 +- .../test/src/models/channel_state_test.dart | 26 + .../test/src/models/message_test.dart | 1 + packages/stream_chat_flutter/CHANGELOG.md | 14 + .../example/.fvm/flutter_sdk | 1 + .../example/.fvm/fvm_config.json | 3 + .../example/android/app/build.gradle | 1 + .../android/app/src/main/AndroidManifest.xml | 2 +- .../kotlin/com/example/example/Application.kt | 17 + .../com/example/example/MainActivity.kt | 8 +- .../res/drawable-v21/launch_background.xml | 12 + .../app/src/main/res/values-night/styles.xml | 18 + .../example/android/build.gradle | 2 +- .../contents.xcworkspacedata | 2 +- .../example/lib/tutorial-part-6.dart | 7 +- .../stream_chat_flutter/example/pubspec.yaml | 6 +- .../example/web/favicon.png | Bin 0 -> 917 bytes .../example/web/icons/Icon-192.png | Bin 0 -> 5292 bytes .../example/web/icons/Icon-512.png | Bin 0 -> 8252 bytes .../example/web/index.html | 47 ++ .../example/web/manifest.json | 23 + .../example/web/sql-wasm.js | 203 +++++++ .../example/web/sql-wasm.wasm | Bin 0 -> 1137969 bytes .../lib/src/attachment/file_attachment.dart | 18 +- .../lib/src/attachment/giphy_attachment.dart | 19 +- .../lib/src/attachment/image_attachment.dart | 37 +- .../lib/src/attachment/video_attachment.dart | 39 +- .../lib/src/attachment_actions_modal.dart | 324 ++++++++++ .../lib/src/back_button.dart | 40 +- .../lib/src/channel_bottom_sheet.dart | 8 +- .../lib/src/channel_file_display_screen.dart | 4 +- .../lib/src/channel_header.dart | 90 ++- .../lib/src/channel_image.dart | 12 +- .../lib/src/channel_info.dart | 7 +- .../lib/src/channel_list_header.dart | 188 +++--- .../lib/src/channel_list_view.dart | 31 +- .../lib/src/channel_media_display_screen.dart | 4 +- .../lib/src/channel_preview.dart | 113 ++-- .../lib/src/extension.dart | 53 ++ .../lib/src/full_screen_media.dart | 2 +- .../lib/src/image_actions_modal.dart | 192 ------ .../lib/src/image_footer.dart | 60 +- .../lib/src/image_header.dart | 7 +- .../lib/src/media_list_view.dart | 10 +- .../lib/src/message_action.dart | 21 + .../lib/src/message_actions_modal.dart | 239 +++----- .../lib/src/message_input.dart | 560 +++++++++++------- .../lib/src/message_list_view.dart | 76 ++- .../lib/src/message_reactions_modal.dart | 6 +- .../lib/src/message_search_list_view.dart | 43 +- .../lib/src/message_text.dart | 3 +- .../lib/src/message_widget.dart | 30 +- .../lib/src/quoted_message_widget.dart | 2 +- .../lib/src/reaction_picker.dart | 26 +- .../lib/src/stream_chat.dart | 10 +- .../lib/src/stream_chat_theme.dart | 137 ++++- .../lib/src/stream_neumorphic_button.dart | 2 +- .../lib/src/stream_svg_icon.dart | 27 +- .../lib/src/system_message.dart | 92 +-- .../lib/src/thread_header.dart | 104 ++-- .../lib/src/unread_indicator.dart | 66 ++- .../lib/src/url_attachment.dart | 18 +- .../lib/src/user_avatar.dart | 43 +- .../stream_chat_flutter/lib/src/utils.dart | 210 +++---- .../lib/src/video_thumbnail_image.dart | 30 +- .../lib/stream_chat_flutter.dart | 1 + packages/stream_chat_flutter/pubspec.yaml | 19 +- .../stream_chat_flutter_core/CHANGELOG.md | 5 + .../lib/src/channels_bloc.dart | 10 +- .../lib/src/message_list_core.dart | 23 +- .../stream_chat_flutter_core/pubspec.yaml | 4 +- packages/stream_chat_persistence/CHANGELOG.md | 4 + .../example/pubspec.yaml | 2 +- packages/stream_chat_persistence/pubspec.yaml | 4 +- 121 files changed, 3757 insertions(+), 2365 deletions(-) create mode 100644 .github/workflows/dispatch_workflows.yml create mode 100644 .github/workflows/pr_title.yml delete mode 100644 packages/stream_chat/lib/src/debounce.dart create mode 100644 packages/stream_chat/lib/src/extensions/rate_limit.dart create mode 120000 packages/stream_chat_flutter/example/.fvm/flutter_sdk create mode 100644 packages/stream_chat_flutter/example/.fvm/fvm_config.json create mode 100644 packages/stream_chat_flutter/example/android/app/src/main/kotlin/com/example/example/Application.kt create mode 100644 packages/stream_chat_flutter/example/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 packages/stream_chat_flutter/example/android/app/src/main/res/values-night/styles.xml create mode 100644 packages/stream_chat_flutter/example/web/favicon.png create mode 100644 packages/stream_chat_flutter/example/web/icons/Icon-192.png create mode 100644 packages/stream_chat_flutter/example/web/icons/Icon-512.png create mode 100644 packages/stream_chat_flutter/example/web/index.html create mode 100644 packages/stream_chat_flutter/example/web/manifest.json create mode 100644 packages/stream_chat_flutter/example/web/sql-wasm.js create mode 100755 packages/stream_chat_flutter/example/web/sql-wasm.wasm create mode 100644 packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart delete mode 100644 packages/stream_chat_flutter/lib/src/image_actions_modal.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_action.dart diff --git a/.github/workflows/dispatch_workflows.yml b/.github/workflows/dispatch_workflows.yml new file mode 100644 index 000000000..5743a0aa9 --- /dev/null +++ b/.github/workflows/dispatch_workflows.yml @@ -0,0 +1,30 @@ +name: dispatch_workflows + +env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + +on: + push: + branches: + - develop + - master + +jobs: + dispatch_nightly: + if: github.ref == 'refs/heads/develop' + runs-on: ubuntu-latest + steps: + - uses: benc-uk/workflow-dispatch@v1 + with: + workflow: build_nightly + repo: GetStream/flutter-samples + token: ${{ secrets.GH_TOKEN }} + dispatch_stable: + if: github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + steps: + - uses: benc-uk/workflow-dispatch@v1 + with: + repo: GetStream/flutter-samples + workflow: build + token: ${{ secrets.GH_TOKEN }} diff --git a/.github/workflows/pana.yml b/.github/workflows/pana.yml index e698349c8..4341e4801 100644 --- a/.github/workflows/pana.yml +++ b/.github/workflows/pana.yml @@ -32,7 +32,7 @@ jobs: TOTAL_MAX: ${{ steps.analysis.outputs.total_max }} run: | PERCENTAGE=$(( $TOTAL * 100 / $TOTAL_MAX )) - if (( $PERCENTAGE < 100 )) + if (( $PERCENTAGE < 90 )) then echo Score too low! exit 1 diff --git a/.github/workflows/pr_title.yml b/.github/workflows/pr_title.yml new file mode 100644 index 000000000..6f4ad786d --- /dev/null +++ b/.github/workflows/pr_title.yml @@ -0,0 +1,22 @@ +name: 'PR Title is Conventional' +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v2.1.0 + with: + scopes: | + llc + persistence + core + ui + requireScope: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/stream_flutter_workflow.yml b/.github/workflows/stream_flutter_workflow.yml index ce6d2c639..25dab1f47 100644 --- a/.github/workflows/stream_flutter_workflow.yml +++ b/.github/workflows/stream_flutter_workflow.yml @@ -30,7 +30,7 @@ jobs: run: melos bootstrap - name: 'Dart Analyze' run: | - melos exec -c 3 -- \ + melos exec -c 3 --ignore="*example*" -- \ tuneup check - name: 'Pub Check' run: | diff --git a/.gitignore b/.gitignore index f7a23bbb4..c75573b20 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,7 @@ build/ .project .classpath .settings -/.fvm +**/.fvm .melos_tool/ /packages/flutter_widgets/example/ios/Flutter/.last_build_id diff --git a/README.md b/README.md index 6260cf244..7f4a523ef 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,9 @@ This repository contains code for our [Dart](https://dart.dev/) and [Flutter](ht Stream allows developers to rapidly deploy scalable feeds and chat messaging with an industry leading 99.999% uptime SLA guarantee. +## 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/stream_chat_v1). + ## 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`. diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 02825f581..4e30d4527 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.4.0-beta + +- Improved attachment uploading +- Fix: update member presence +- Added skip_push to message model +- Minor fixes and improvements + ## 1.3.2+1-beta - Fixed queryChannels bug diff --git a/packages/stream_chat/analysis_options.yaml b/packages/stream_chat/analysis_options.yaml index 24e35a1f0..7e4b00faf 100644 --- a/packages/stream_chat/analysis_options.yaml +++ b/packages/stream_chat/analysis_options.yaml @@ -1,63 +1,147 @@ -include: package:pedantic/analysis_options.yaml - analyzer: - exclude: + exclude: - lib/**/*.g.dart - lib/**/*.freezed.dart - example/* - test/* - -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 +linter: + rules: + - always_use_package_imports - avoid_empty_else - - avoid_init_to_null - - avoid_return_types_on_setters - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_types + - avoid_relative_lib_imports + - avoid_slow_async_io + - avoid_types_as_parameter_names - 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 + - diagnostic_describe_all_properties - empty_statements - hash_and_equals + - invariant_booleans + - iterable_contains_unrelated_type + - list_remove_unrelated_type + - literal_only_boolean_expressions + - no_adjacent_strings_in_list + - no_duplicate_case_values + - no_logic_in_create_state + - prefer_void_to_null + - test_types_in_equals + - throw_in_finally + - unnecessary_statements + - unrelated_type_equality_checks + - omit_local_variable_types + - use_key_in_widget_constructors + - valid_regexps + - always_declare_return_types + - always_put_required_named_parameters_first + - always_require_non_null_named_parameters + - annotate_overrides + - avoid_bool_literals_in_conditional_expressions + - avoid_catching_errors + - avoid_init_to_null + - avoid_null_checks_in_equality_operators + - avoid_positional_boolean_parameters + - avoid_private_typedef_functions + - avoid_redundant_argument_values + - avoid_return_types_on_setters + - avoid_returning_null + - avoid_returning_null_for_void + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_unnecessary_containers + - avoid_unused_constructor_parameters + - await_only_futures + - camel_case_extensions + - camel_case_types + - cascade_invocations + + - constant_identifier_names + - curly_braces_in_flow_control_structures + - directives_ordering + - empty_catches + - empty_constructor_bodies + - exhaustive_cases + - file_names - implementation_imports - # - invariant_booleans - # - iterable_contains_unrelated_type + - join_return_with_assignment + - leading_newlines_in_multiline_strings - library_names - # - library_prefixes - # - list_remove_unrelated_type - # - literal_only_boolean_expressions + - library_prefixes + - lines_longer_than_80_chars + - missing_whitespace_between_adjacent_strings - non_constant_identifier_names - # - one_member_abstracts - # - only_throw_errors - # - overridden_fields + - null_closures + - one_member_abstracts + - only_throw_errors - package_api_docs - - package_names - package_prefixed_library_names + - parameter_assignments + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + - prefer_asserts_with_message + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + - prefer_constructors_over_static_methods + - prefer_contains + - prefer_equal_for_default_values + - prefer_expression_function_bodies + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + - prefer_function_declarations_over_variables + - prefer_generic_function_type_aliases + - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + - prefer_int_literals + - prefer_interpolation_to_compose_strings + - prefer_is_empty - prefer_is_not_empty - # - prefer_mixin # https://github.com/dart-lang/language/issues/32 + - prefer_is_not_operator + - prefer_null_aware_operators + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - provide_deprecation_message - public_member_api_docs + - recursive_getters + - sized_box_for_whitespace - 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 + - sort_child_properties_last + - sort_constructors_first + - sort_unnamed_constructors_first + + - type_annotate_public_apis - type_init_formals - # - unawaited_futures + - unnecessary_await_in_return - unnecessary_brace_in_string_interps + - unnecessary_const - unnecessary_getters_setters - - unnecessary_statements - - unrelated_type_equality_checks - - valid_regexps \ No newline at end of file + - unnecessary_lambdas + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations + - unnecessary_parenthesis + - unnecessary_raw_strings + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this + - use_is_even_rather_than_modulo + - use_late_for_private_fields_and_variables + - use_rethrow_when_possible + - use_setters_to_change_properties + - use_to_and_as_if_applicable + - package_names + - sort_pub_dependencies + + # To be added when null-safe: + # - cast_nullable_to_non_nullable + #- unnecessary_null_checks + # - tighten_type_of_initializing_formals + # - null_check_on_nullable_type_parameter \ No newline at end of file diff --git a/packages/stream_chat/lib/src/api/channel.dart b/packages/stream_chat/lib/src/api/channel.dart index 8814bfb09..76209bfd0 100644 --- a/packages/stream_chat/lib/src/api/channel.dart +++ b/packages/stream_chat/lib/src/api/channel.dart @@ -2,24 +2,16 @@ import 'dart:async'; import 'dart:convert'; import 'dart:math'; -import 'package:pedantic/pedantic.dart' show unawaited; import 'package:dio/dio.dart'; import 'package:logging/logging.dart'; import 'package:rxdart/rxdart.dart'; import 'package:stream_chat/src/api/retry_queue.dart'; -import 'package:stream_chat/src/debounce.dart'; import 'package:stream_chat/src/event_type.dart'; import 'package:stream_chat/src/models/attachment_file.dart'; import 'package:stream_chat/src/models/channel_state.dart'; import 'package:stream_chat/src/models/user.dart'; import 'package:stream_chat/stream_chat.dart'; - -import '../client.dart'; -import '../models/event.dart'; -import '../models/member.dart'; -import '../models/message.dart'; -import 'requests.dart'; -import 'responses.dart'; +import 'package:stream_chat/src/extensions/rate_limit.dart'; /// This a the class that manages a specific channel. class Channel { @@ -57,7 +49,8 @@ class Channel { set extraData(Map extraData) { if (_initializedCompleter.isCompleted) { throw Exception( - 'Once the channel is initialized you should use channel.update to update channel data'); + 'Once the channel is initialized you should use channel.update ' + 'to update channel data'); } _extraData = extraData; } @@ -168,14 +161,15 @@ class Channel { final Completer _initializedCompleter = Completer(); /// True if this is initialized - /// Call [watch] to initialize the client or instantiate it using [Channel.fromState] + /// Call [watch] to initialize the client or instantiate it using + /// [Channel.fromState] Future get initialized => _initializedCompleter.future; final _cancelableAttachmentUploadRequest = {}; final _messageAttachmentsUploadCompleter = {}; - /// Cancels [attachmentId] upload request. Throws exception if the request hasn't - /// even started yet, Already completed or Already cancelled. + /// Cancels [attachmentId] upload request. Throws exception if the request + /// hasn't even started yet, Already completed or Already cancelled. /// /// Optionally, provide a [reason] for the cancellation. void cancelAttachmentUpload( @@ -185,7 +179,8 @@ class Channel { final cancelToken = _cancelableAttachmentUploadRequest[attachmentId]; if (cancelToken == null) { throw Exception( - "Upload request for this Attachment hasn't started yet or else Already completed", + "Upload request for this Attachment hasn't started yet or else " + 'Already completed', ); } if (cancelToken.isCancelled) throw Exception('Already cancelled'); @@ -193,15 +188,14 @@ class Channel { } /// Retries the failed [attachmentId] upload request. - Future retryAttachmentUpload(String messageId, String attachmentId) { - return _uploadAttachments(messageId, [attachmentId]); - } + Future retryAttachmentUpload(String messageId, String attachmentId) => + _uploadAttachments(messageId, [attachmentId]); Future _uploadAttachments( String messageId, Iterable attachmentIds, ) { - var message = state.messages.firstWhere( + final message = state.messages.firstWhere( (it) => it.id == messageId, orElse: () => null, ); @@ -224,29 +218,29 @@ class Channel { } client.logger.info('Found ${attachments.length} attachments'); + + void updateAttachment(Attachment attachment) { + final index = + message.attachments.indexWhere((it) => it.id == attachment.id); + if (index != -1) { + message.attachments[index] = attachment; + state?.addMessage(message); + } + } + return Future.wait(attachments.map((it) { client.logger.info('Uploading ${it.id} attachment...'); - void updateAttachment(Attachment attachment) { - final index = message.attachments.indexWhere((it) { - return it.id == attachment.id; - }); - if (index != -1) { - message.attachments[index] = attachment; - state?.addMessage(message); - } - } + final throttledUpdateAttachment = updateAttachment.throttled( + const Duration(milliseconds: 500), + ); void onSendProgress(int sent, int total) { - debounce( - timeout: Duration(seconds: 1), - target: updateAttachment, - positionalArguments: [ - it.copyWith( - uploadState: UploadState.inProgress(uploaded: sent, total: total), - ), - ], - ); + throttledUpdateAttachment([ + it.copyWith( + uploadState: UploadState.inProgress(uploaded: sent, total: total), + ), + ]); } final isImage = it.type == 'image'; @@ -270,18 +264,26 @@ class Channel { client.logger.info('Attachment ${it.id} uploaded successfully...'); if (isImage) { updateAttachment( - it.copyWith(imageUrl: url, uploadState: UploadState.success()), + it.copyWith( + imageUrl: url, + uploadState: const UploadState.success(), + ), ); } else { updateAttachment( - it.copyWith(assetUrl: url, uploadState: UploadState.success()), + it.copyWith( + assetUrl: url, + uploadState: const UploadState.success(), + ), ); } }).catchError((e, stk) { + client.logger.severe('error uploading the attachment', e, stk); updateAttachment( it.copyWith(uploadState: UploadState.failed(error: e.toString())), ); }).whenComplete(() { + throttledUpdateAttachment?.cancel(); _cancelableAttachmentUploadRequest.remove(it.id); }); })).whenComplete(() { @@ -305,6 +307,7 @@ class Channel { (m) => m.id == message?.quotedMessageId, orElse: () => null, ); + // ignore: parameter_assignments message = message.copyWith( createdAt: message.createdAt ?? DateTime.now(), user: _client.state.user, @@ -313,7 +316,7 @@ class Channel { attachments: message.attachments?.map( (it) { if (it.uploadState.isSuccess) return it; - return it.copyWith(uploadState: UploadState.preparing()); + return it.copyWith(uploadState: const UploadState.preparing()); }, )?.toList(), ); @@ -335,11 +338,13 @@ class Channel { _messageAttachmentsUploadCompleter[message.id] = attachmentsUploadCompleter; - unawaited(_uploadAttachments( + // ignore: unawaited_futures + _uploadAttachments( message.id, message.attachments.map((it) => it.id), - )); + ); + // ignore: parameter_assignments message = await attachmentsUploadCompleter.future; } @@ -364,13 +369,14 @@ class Channel { .remove(message.id) ?.completeError('Message Cancelled'); + // ignore: parameter_assignments message = message.copyWith( status: MessageSendingStatus.updating, updatedAt: message.updatedAt ?? DateTime.now(), attachments: message.attachments?.map( (it) { if (it.uploadState.isSuccess) return it; - return it.copyWith(uploadState: UploadState.preparing()); + return it.copyWith(uploadState: const UploadState.preparing()); }, )?.toList(), ); @@ -383,11 +389,13 @@ class Channel { _messageAttachmentsUploadCompleter[message.id] = attachmentsUploadCompleter; - unawaited(_uploadAttachments( + // ignore: unawaited_futures + _uploadAttachments( message.id, message.attachments.map((it) => it.id), - )); + ); + // ignore: parameter_assignments message = await attachmentsUploadCompleter.future; } @@ -423,6 +431,7 @@ class Channel { } try { + // ignore: parameter_assignments message = message.copyWith( type: 'deleted', status: MessageSendingStatus.deleting, @@ -456,7 +465,7 @@ class Channel { throw ArgumentError('Invalid timeout or Expiration date'); } return true; - }()); + }(), 'Check for invalid token or expiration date'); DateTime pinExpires; if (timeoutOrExpirationDate is DateTime) { @@ -475,39 +484,36 @@ class Channel { } /// Unpins provided message - Future unpinMessage(Message message) { - return updateMessage(message.copyWith(pinned: false)); - } + Future unpinMessage(Message message) => + updateMessage(message.copyWith(pinned: false)); /// Send a file to this channel Future sendFile( AttachmentFile file, { ProgressCallback onSendProgress, CancelToken cancelToken, - }) { - return _client.sendFile( - file, - id, - type, - onSendProgress: onSendProgress, - cancelToken: cancelToken, - ); - } + }) => + _client.sendFile( + file, + id, + type, + onSendProgress: onSendProgress, + cancelToken: cancelToken, + ); /// Send an image to this channel Future sendImage( AttachmentFile file, { ProgressCallback onSendProgress, CancelToken cancelToken, - }) { - return _client.sendImage( - file, - id, - type, - onSendProgress: onSendProgress, - cancelToken: cancelToken, - ); - } + }) => + _client.sendImage( + file, + id, + type, + onSendProgress: onSendProgress, + cancelToken: cancelToken, + ); /// A message search. Future search({ @@ -515,35 +521,32 @@ class Channel { Map messageFilters, List sort, PaginationParams paginationParams, - }) { - return _client.search( - { - 'cid': { - r'$in': [cid], + }) => + _client.search( + { + 'cid': { + r'$in': [cid], + }, }, - }, - sort: sort, - query: query, - paginationParams: paginationParams, - messageFilters: messageFilters, - ); - } + sort: sort, + query: query, + paginationParams: paginationParams, + messageFilters: messageFilters, + ); /// Delete a file from this channel Future deleteFile( String url, { CancelToken cancelToken, - }) { - return _client.deleteFile(url, id, type, cancelToken: cancelToken); - } + }) => + _client.deleteFile(url, id, type, cancelToken: cancelToken); /// Delete an image from this channel Future deleteImage( String url, { CancelToken cancelToken, - }) { - return _client.deleteImage(url, id, type, cancelToken: cancelToken); - } + }) => + _client.deleteImage(url, id, type, cancelToken: cancelToken); /// Send an event on this channel Future sendEvent(Event event) { @@ -551,9 +554,7 @@ class Channel { return _client.post( '$_channelURL/event', data: {'event': event.toJson()}, - ).then((res) { - return _client.decode(res.data, EmptyResponse.fromJson); - }); + ).then((res) => _client.decode(res.data, EmptyResponse.fromJson)); } /// Send a reaction to this channel @@ -643,11 +644,10 @@ class Channel { } final latestReactions = [...message.latestReactions ?? []] - ..removeWhere((r) { - return r.userId == reaction.userId && - r.type == reaction.type && - r.messageId == reaction.messageId; - }); + ..removeWhere((r) => + r.userId == reaction.userId && + r.type == reaction.type && + r.messageId == reaction.messageId); final ownReactions = [...latestReactions ?? []] ..removeWhere((it) => it.userId != user.id); @@ -825,7 +825,7 @@ class Channel { }) ..addAll(options); - var response; + ChannelState response; try { response = await query(options: watchOptions); @@ -861,7 +861,8 @@ class Channel { } /// List the message replies for a parent message - /// Set [preferOffline] to true to avoid the api call if the data is already in the offline storage + /// Set [preferOffline] to true to avoid the api call if the data is already + /// in the offline storage Future getReplies( String parentId, PaginationParams options, { @@ -940,16 +941,15 @@ class Channel { } /// Creates a new channel - Future create() async { - return query(options: { - 'watch': false, - 'state': false, - 'presence': false, - }); - } + Future create() async => query(options: { + 'watch': false, + 'state': false, + 'presence': false, + }); /// Query the API, get messages, members or other channel fields - /// Set [preferOffline] to true to avoid the api call if the data is already in the offline storage + /// Set [preferOffline] to true to avoid the api call if the data is already + /// in the offline storage Future query({ Map options = const {}, PaginationParams messagesPagination, @@ -1112,8 +1112,9 @@ class Channel { }); } - /// Hides the channel from [StreamChatClient.queryChannels] for the user until a message is added - /// If [clearHistory] is set to true - all messages will be removed for the user + /// Hides the channel from [StreamChatClient.queryChannels] for the user + /// until a message is added If [clearHistory] is set to true - all messages + /// will be removed for the user Future hide({bool clearHistory = false}) async { _checkInitialized(); final response = await _client @@ -1134,28 +1135,28 @@ class Channel { return _client.decode(response.data, EmptyResponse.fromJson); } - /// Stream of [Event] coming from websocket connection specific for the channel - /// Pass an eventType as parameter in order to filter just a type of event + /// Stream of [Event] coming from websocket connection specific for the + /// channel. Pass an eventType as parameter in order to filter just a type + /// of event Stream on([ String eventType, String eventType2, String eventType3, String eventType4, - ]) { - return _client - .on( - eventType, - eventType2, - eventType3, - eventType4, - ) - .where((e) => e.cid == cid); - } + ]) => + _client + .on( + eventType, + eventType2, + eventType3, + eventType4, + ) + .where((e) => e.cid == cid); DateTime _lastTypingEvent; - /// First of the [EventType.typingStart] and [EventType.typingStop] events based on the users keystrokes. - /// Call this on every keystroke. + /// First of the [EventType.typingStart] and [EventType.typingStop] events + /// based on the users keystrokes. Call this on every keystroke. Future keyStroke([String parentId]) async { if (config?.typingEvents == false) { return; @@ -1196,17 +1197,21 @@ class Channel { void _checkInitialized() { if (!_initializedCompleter.isCompleted) { throw Exception( - "Channel $cid hasn't been initialized yet. Make sure to call .watch() or to instantiate the client using [Channel.fromState]"); + "Channel $cid hasn't been initialized yet. Make sure to call .watch()" + ' or to instantiate the client using [Channel.fromState]'); } } } /// The class that handles the state of the channel listening to the events class ChannelClientState { - final _subscriptions = []; - /// Creates a new instance listening to events and updating the state - ChannelClientState(this._channel, ChannelState channelState) { + ChannelClientState( + this._channel, + ChannelState channelState, + ) : _debouncedUpdatePersistenceChannelState = _channel + ?._client?.chatPersistenceClient?.updateChannelState + ?.debounced(const Duration(seconds: 1)) { retryQueue = RetryQueue( channel: _channel, logger: Logger('RETRY QUEUE ${_channel.cid}'), @@ -1252,14 +1257,16 @@ class ChannelClientState { _channel._client.chatPersistenceClient ?.getChannelStateByCid(_channel.cid) ?.then((state) { - // Replacing the persistence state members with the latest `channelState.members` - // as they may have changes over the time. + // Replacing the persistence state members with the latest + // `channelState.members` as they may have changes over the time. updateChannelState(state.copyWith(members: channelState.members)); retryFailedMessages(); }); }); } + final _subscriptions = []; + void _computeInitialUnread() { final userRead = channelState?.read?.firstWhere( (r) => r.user.id == _channel._client.state?.user?.id, @@ -1277,11 +1284,16 @@ class ChannelClientState { m.attachments?.isNotEmpty == true && m.attachments?.any((e) { final url = e.imageUrl ?? e.assetUrl; - if (url == null || !url.contains('stream-io-cdn.com')) { + if (url == null || !url.contains('')) { + return false; + } + final uri = Uri.parse(url); + if (uri.host != 'stream-io-cdn.com' || + uri.queryParameters['Expires'] == null) { return false; } final expiration = - DateTime.parse(Uri.parse(url).queryParameters['Expires']); + DateTime.parse(uri.queryParameters['Expires']); return expiration.isBefore(DateTime.now()); }) == true) @@ -1338,8 +1350,8 @@ class ChannelClientState { /// Flag which indicates if [ChannelClientState] contain latest/recent messages or not. /// This flag should be managed by UI sdks. - /// When false, any new message (received by WebSocket event - [EventType.messageNew]) will not - /// be pushed on to message list. + /// When false, any new message (received by WebSocket event + /// - [EventType.messageNew]) will not be pushed on to message list. bool get isUpToDate => _isUpToDateController.value; set isUpToDate(bool isUpToDate) => _isUpToDateController.add(isUpToDate); @@ -1357,12 +1369,18 @@ class ChannelClientState { Future retryFailedMessages() async { final failedMessages = [...messages, ...threads.values.expand((v) => v)] - .where((message) => - message.status != null && - message.status != MessageSendingStatus.sent && - message.createdAt.isBefore(DateTime.now().subtract(Duration( - seconds: 1, - )))) + .where( + (message) => + message.status != null && + message.status != MessageSendingStatus.sent && + message.createdAt.isBefore( + DateTime.now().subtract( + const Duration( + seconds: 1, + ), + ), + ), + ) .toList(); retryQueue.add(failedMessages); @@ -1471,27 +1489,32 @@ class ChannelClientState { return; } - _subscriptions.add(_channel - .on( - EventType.messageRead, - EventType.notificationMarkRead, - ) - .listen((event) { - final readList = List.from(_channelState?.read ?? []); - final userReadIndex = read?.indexWhere((r) => r.user.id == event.user.id); - - if (userReadIndex != null && userReadIndex != -1) { - final userRead = readList.removeAt(userReadIndex); - if (userRead.user?.id == _channel._client.state.user.id) { - _unreadCountController.add(0); - } - readList.add(Read( - user: event.user, - lastRead: event.createdAt, - )); - _channelState = _channelState.copyWith(read: readList); - } - })); + _subscriptions.add( + _channel + .on( + EventType.messageRead, + EventType.notificationMarkRead, + ) + .listen( + (event) { + final readList = List.from(_channelState?.read ?? []); + final userReadIndex = + read?.indexWhere((r) => r.user.id == event.user.id); + + if (userReadIndex != null && userReadIndex != -1) { + final userRead = readList.removeAt(userReadIndex); + if (userRead.user?.id == _channel._client.state.user.id) { + _unreadCountController.add(0); + } + readList.add(Read( + user: event.user, + lastRead: event.createdAt, + )); + _channelState = _channelState.copyWith(read: readList); + } + }, + ), + ); } /// Channel message list @@ -1527,11 +1550,8 @@ class ChannelClientState { List, Map, List>( channelStateStream.map((cs) => cs.members), _channel.client.state.usersStream, - (members, users) { - return members - .map((e) => e.copyWith(user: users[e.user.id])) - .toList(); - }, + (members, users) => + members.map((e) => e.copyWith(user: users[e.user.id])).toList(), ); /// Channel watcher count @@ -1551,9 +1571,7 @@ class ChannelClientState { CombineLatestStream.combine2, Map, List>( channelStateStream.map((cs) => cs.watchers), _channel.client.state.usersStream, - (watchers, users) { - return watchers.map((e) => users[e.id] ?? e).toList(); - }, + (watchers, users) => watchers.map((e) => users[e.id] ?? e).toList(), ); /// Channel read list @@ -1625,9 +1643,7 @@ class ChannelClientState { true) ?.toList() ?? [], - ]; - - newMessages.sort(_sortByCreatedAt); + ]..sort(_sortByCreatedAt); final newWatchers = [ ...updatedState?.watchers ?? [], @@ -1690,16 +1706,11 @@ class ChannelClientState { ChannelState get channelState => _channelStateController.value; BehaviorSubject _channelStateController; + final Debounce _debouncedUpdatePersistenceChannelState; + set _channelState(ChannelState v) { _channelStateController.add(v); - - if (_channel._client.persistenceEnabled) { - debounce( - timeout: Duration(milliseconds: 500), - target: _channel._client.chatPersistenceClient?.updateChannelState, - positionalArguments: [v], - ); - } + _debouncedUpdatePersistenceChannelState?.call([v]); } /// The channel threads related to this channel @@ -1735,28 +1746,62 @@ class ChannelClientState { return; } - _subscriptions.add(_channel.on(EventType.typingStart).listen((event) { - if (event.user.id != _channel.client.state.user.id) { - _typings[event.user] = DateTime.now(); - _typingEventsController.add(_typings.keys.toList()); - } - })); - - _subscriptions.add(_channel.on(EventType.typingStop).listen((event) { - if (event.user.id != _channel.client.state.user.id) { - _typings.remove(event.user); - _typingEventsController.add(_typings.keys.toList()); - } - })); + _subscriptions + ..add( + _channel.on(EventType.typingStart).listen( + (event) { + if (event.user.id != _channel.client.state.user.id) { + _typings[event.user] = DateTime.now(); + _typingEventsController.add(_typings.keys.toList()); + } + }, + ), + ) + ..add( + _channel.on(EventType.typingStop).listen( + (event) { + if (event.user.id != _channel.client.state.user.id) { + _typings.remove(event.user); + _typingEventsController.add(_typings.keys.toList()); + } + }, + ), + ) + ..add( + _channel + .on() + .where((event) => + event.user != null && + members?.any((m) => m.userId == event.user.id) == true) + .listen( + (event) { + final newMembers = List.from(members); + final oldMemberIndex = + newMembers.indexWhere((m) => m.userId == event.user.id); + if (oldMemberIndex > -1) { + final oldMember = newMembers.removeAt(oldMemberIndex); + updateChannelState(ChannelState( + members: [ + ...newMembers, + oldMember.copyWith( + user: event.user, + ), + ], + )); + } + }, + ), + ); } Timer _cleaningTimer; + void _startCleaning() { if (_channel.config?.typingEvents == false) { return; } - _cleaningTimer = Timer.periodic(Duration(seconds: 1), (_) { + _cleaningTimer = Timer.periodic(const Duration(seconds: 1), (_) { final now = DateTime.now(); if (_channel._lastTypingEvent != null && @@ -1769,8 +1814,9 @@ class ChannelClientState { } Timer _pinnedMessagesTimer; + void _startCleaningPinnedMessages() { - _pinnedMessagesTimer = Timer.periodic(Duration(seconds: 30), (_) { + _pinnedMessagesTimer = Timer.periodic(const Duration(seconds: 30), (_) { final now = DateTime.now(); var expiredMessages = channelState.pinnedMessages ?.where((m) => m.pinExpires?.isBefore(now) == true) @@ -1781,8 +1827,6 @@ class ChannelClientState { .map((m) => m.copyWith( pinExpires: null, pinned: false, - pinnedAt: null, - pinnedBy: null, )) .toList(); @@ -1811,6 +1855,7 @@ class ChannelClientState { /// Call this method to dispose this object void dispose() { + _debouncedUpdatePersistenceChannelState?.cancel(); _unreadCountController.close(); retryQueue.dispose(); _subscriptions.forEach((s) => s.cancel()); diff --git a/packages/stream_chat/lib/src/api/requests.dart b/packages/stream_chat/lib/src/api/requests.dart index 414113de8..764d249a8 100644 --- a/packages/stream_chat/lib/src/api/requests.dart +++ b/packages/stream_chat/lib/src/api/requests.dart @@ -5,10 +5,25 @@ part 'requests.g.dart'; /// Sorting options @JsonSerializable(createFactory: false) class SortOption { + /// Creates a new SortOption instance + /// + /// For example: + /// ```dart + /// // Sort channels by the last message date: + /// final sorting = SortOption("last_message_at") + /// ``` + const SortOption( + this.field, { + this.direction = DESC, + this.comparator, + }); + /// Ascending order + // ignore: constant_identifier_names static const ASC = 1; /// Descending order + // ignore: constant_identifier_names static const DESC = -1; /// A sorting field name @@ -21,19 +36,6 @@ class SortOption { @JsonKey(ignore: true) final Comparator comparator; - /// Creates a new SortOption instance - /// - /// For example: - /// ```dart - /// // Sort channels by the last message date: - /// final sorting = SortOption("last_message_at") - /// ``` - const SortOption( - this.field, { - this.direction = DESC, - this.comparator, - }); - /// Serialize model to json Map toJson() => _$SortOptionToJson(this); } @@ -41,6 +43,25 @@ class SortOption { /// Pagination options. @JsonSerializable(createFactory: false, includeIfNull: false) class PaginationParams { + /// Creates a new PaginationParams instance + /// + /// For example: + /// ```dart + /// // limit to 50 + /// final paginationParams = PaginationParams(limit: 50); + /// + /// // limit to 50 with offset + /// final paginationParams = PaginationParams(limit: 50, offset: 50); + /// ``` + const PaginationParams({ + this.limit = 10, + this.offset = 0, + this.greaterThan, + this.greaterThanOrEqual, + this.lessThan, + this.lessThanOrEqual, + }); + /// The amount of items requested from the APIs. final int limit; @@ -63,25 +84,6 @@ class PaginationParams { @JsonKey(name: 'id_lte') final String lessThanOrEqual; - /// Creates a new PaginationParams instance - /// - /// For example: - /// ```dart - /// // limit to 50 - /// final paginationParams = PaginationParams(limit: 50); - /// - /// // limit to 50 with offset - /// final paginationParams = PaginationParams(limit: 50, offset: 50); - /// ``` - const PaginationParams({ - this.limit = 10, - this.offset = 0, - this.greaterThan, - this.greaterThanOrEqual, - this.lessThan, - this.lessThanOrEqual, - }); - /// Serialize model to json Map toJson() => _$PaginationParamsToJson(this); diff --git a/packages/stream_chat/lib/src/api/requests.g.dart b/packages/stream_chat/lib/src/api/requests.g.dart index ef7907761..f020c1ea4 100644 --- a/packages/stream_chat/lib/src/api/requests.g.dart +++ b/packages/stream_chat/lib/src/api/requests.g.dart @@ -6,7 +6,7 @@ part of 'requests.dart'; // JsonSerializableGenerator // ************************************************************************** -Map _$SortOptionToJson(SortOption instance) => +Map _$SortOptionToJson(SortOption instance) => { 'field': instance.field, 'direction': instance.direction, diff --git a/packages/stream_chat/lib/src/api/responses.dart b/packages/stream_chat/lib/src/api/responses.dart index a1e928d65..431a57e79 100644 --- a/packages/stream_chat/lib/src/api/responses.dart +++ b/packages/stream_chat/lib/src/api/responses.dart @@ -1,15 +1,14 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:stream_chat/src/client.dart'; +import 'package:stream_chat/src/models/channel_model.dart'; +import 'package:stream_chat/src/models/channel_state.dart'; import 'package:stream_chat/src/models/device.dart'; import 'package:stream_chat/src/models/event.dart'; - -import '../models/channel_model.dart'; -import '../models/channel_state.dart'; -import '../models/member.dart'; -import '../models/message.dart'; -import '../models/reaction.dart'; -import '../models/read.dart'; -import '../models/user.dart'; +import 'package:stream_chat/src/models/member.dart'; +import 'package:stream_chat/src/models/message.dart'; +import 'package:stream_chat/src/models/reaction.dart'; +import 'package:stream_chat/src/models/read.dart'; +import 'package:stream_chat/src/models/user.dart'; part 'responses.g.dart'; diff --git a/packages/stream_chat/lib/src/api/retry_policy.dart b/packages/stream_chat/lib/src/api/retry_policy.dart index 2c59ec48b..a4d1e7bd8 100644 --- a/packages/stream_chat/lib/src/api/retry_policy.dart +++ b/packages/stream_chat/lib/src/api/retry_policy.dart @@ -18,7 +18,8 @@ class RetryPolicy { final bool Function(StreamChatClient client, int attempt, ApiError apiError) shouldRetry; - /// In the case that we want to retry a failed request the retryTimeout method is called to determine the timeout + /// In the case that we want to retry a failed request the retryTimeout + /// method is called to determine the timeout final Duration Function( StreamChatClient client, int attempt, ApiError apiError) retryTimeout; diff --git a/packages/stream_chat/lib/src/api/retry_queue.dart b/packages/stream_chat/lib/src/api/retry_queue.dart index 340465457..ac0e14d77 100644 --- a/packages/stream_chat/lib/src/api/retry_queue.dart +++ b/packages/stream_chat/lib/src/api/retry_queue.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:collection/collection.dart'; -import 'package:meta/meta.dart'; import 'package:logging/logging.dart'; +import 'package:meta/meta.dart'; import 'package:stream_chat/src/api/channel.dart'; import 'package:stream_chat/src/api/retry_policy.dart'; import 'package:stream_chat/src/event_type.dart'; @@ -12,12 +12,6 @@ import 'package:stream_chat/stream_chat.dart'; /// The retry queue associated to a channel class RetryQueue { - /// The channel of this queue - final Channel channel; - - /// The logger associated to this queue - final Logger logger; - /// Instantiate a new RetryQueue object RetryQueue({ @required this.channel, @@ -30,6 +24,12 @@ class RetryQueue { _listenFailedEvents(); } + /// The channel of this queue + final Channel channel; + + /// The logger associated to this queue + final Logger logger; + final _subscriptions = []; void _listenConnectionRecovered() { diff --git a/packages/stream_chat/lib/src/api/websocket.dart b/packages/stream_chat/lib/src/api/websocket.dart index 15102c6e4..ea2bb291b 100644 --- a/packages/stream_chat/lib/src/api/websocket.dart +++ b/packages/stream_chat/lib/src/api/websocket.dart @@ -2,28 +2,29 @@ import 'dart:async'; import 'dart:convert'; import 'dart:math'; -import 'package:meta/meta.dart'; import 'package:logging/logging.dart'; +import 'package:meta/meta.dart'; import 'package:rxdart/rxdart.dart'; -import 'package:web_socket_channel/web_socket_channel.dart'; - -import '../models/event.dart'; -import '../models/user.dart'; -import 'connection_status.dart'; -import 'web_socket_channel_stub.dart' +import 'package:stream_chat/src/api/connection_status.dart'; +import 'package:stream_chat/src/api/web_socket_channel_stub.dart' if (dart.library.html) 'web_socket_channel_html.dart' if (dart.library.io) 'web_socket_channel_io.dart'; +import 'package:stream_chat/src/models/event.dart'; +import 'package:stream_chat/src/models/user.dart'; +import 'package:web_socket_channel/web_socket_channel.dart'; /// Typedef which exposes an [Event] as the only parameter. typedef EventHandler = void Function(Event); -/// Typedef used for connecting to a websocket. Method returns a [WebSocketChannel] -/// and accepts a connection [url] and an optional [Iterable] of `protocols`. +/// Typedef used for connecting to a websocket. Method returns a +/// [WebSocketChannel] and accepts a connection [url] and an optional +/// [Iterable] of `protocols`. typedef ConnectWebSocket = WebSocketChannel Function(String url, {Iterable protocols}); // TODO: parse error even -// TODO: if parsing an error into an event fails we should not hide the original error +// TODO: if parsing an error into an event fails we should not hide the +// TODO: original error /// A WebSocket connection that reconnects upon failure. class WebSocket { /// Creates a new websocket @@ -75,7 +76,8 @@ class WebSocket { /// WS connection payload final Map connectPayload; - /// Functions that will be called every time a new event is received from the connection + /// Functions that will be called every time a new event is received from the + /// connection final EventHandler handler; /// A WS specific logger instance @@ -87,8 +89,9 @@ class WebSocket { final ConnectWebSocket connectFunc; /// Interval of the reconnection monitor timer - /// This checks that it received a new event in the last [reconnectionMonitorTimeout] seconds, - /// otherwise it considers the connection unhealthy and reconnects the WS + /// This checks that it received a new event in the last + /// [reconnectionMonitorTimeout] seconds, otherwise it considers the + /// connection unhealthy and reconnects the WS final int reconnectionMonitorInterval; /// Interval of the health event sending timer @@ -96,7 +99,8 @@ class WebSocket { /// make the server aware that the client is still listening final int healthCheckInterval; - /// The timeout that uses the reconnection monitor timer to consider the connection unhealthy + /// The timeout that uses the reconnection monitor timer to consider the + /// connection unhealthy final int reconnectionMonitorTimeout; final _connectionStatusController = @@ -121,9 +125,7 @@ class WebSocket { _connecting = false, _reconnecting = false; - Event _decodeEvent(String source) { - return Event.fromJson(json.decode(source)); - } + Event _decodeEvent(String source) => Event.fromJson(json.decode(source)); Completer _connectionCompleter = Completer(); @@ -166,8 +168,8 @@ class WebSocket { return; } - logger.info( - 'connection closed | closeCode: ${_channel.closeCode} | closedReason: ${_channel.closeReason}'); + logger.info('connection closed | closeCode: ${_channel.closeCode} | ' + 'closedReason: ${_channel.closeReason}'); if (!_reconnecting) { _reconnect(); @@ -200,8 +202,7 @@ class WebSocket { } Future _onConnectionError(error, [stacktrace]) async { - logger.severe('error connecting'); - logger.severe(error); + logger..severe('error connecting')..severe(error); if (stacktrace != null) { logger.severe(stacktrace); } @@ -219,21 +220,21 @@ class WebSocket { } } - void _startReconnectionMonitor() { - final reconnectionTimer = (_) { - final now = DateTime.now(); - if (_lastEventAt != null && - now.difference(_lastEventAt).inSeconds > reconnectionMonitorTimeout) { - _channel.sink.close(); - } - }; + void _reconnectionTimer(_) { + final now = DateTime.now(); + if (_lastEventAt != null && + now.difference(_lastEventAt).inSeconds > reconnectionMonitorTimeout) { + _channel.sink.close(); + } + } + void _startReconnectionMonitor() { _reconnectionMonitor = Timer.periodic( Duration(seconds: reconnectionMonitorInterval), - reconnectionTimer, + _reconnectionTimer, ); - reconnectionTimer(_reconnectionMonitor); + _reconnectionTimer(_reconnectionMonitor); } void _reconnectTimer() async { @@ -283,20 +284,20 @@ class WebSocket { } } + void _healthCheckTimer(_) { + logger.info('sending health.check'); + _channel.sink.add("{'type': 'health.check'}"); + } + void _startHealthCheck() { logger.info('start health check monitor'); - final healthCheckTimer = (_) { - logger.info('sending health.check'); - _channel.sink.add("{'type': 'health.check'}"); - }; - _healthCheck = Timer.periodic( Duration(seconds: healthCheckInterval), - healthCheckTimer, + _healthCheckTimer, ); - healthCheckTimer(_healthCheck); + _healthCheckTimer(_healthCheck); } /// Disconnects the WS and releases eventual resources diff --git a/packages/stream_chat/lib/src/attachment_file_uploader.dart b/packages/stream_chat/lib/src/attachment_file_uploader.dart index c420728f0..7d9e8c402 100644 --- a/packages/stream_chat/lib/src/attachment_file_uploader.dart +++ b/packages/stream_chat/lib/src/attachment_file_uploader.dart @@ -1,8 +1,8 @@ import 'package:dio/dio.dart'; import 'package:stream_chat/src/api/responses.dart'; +import 'package:stream_chat/src/client.dart'; import 'package:stream_chat/src/models/attachment_file.dart'; -import 'client.dart'; -import 'extensions/string_extension.dart'; +import 'package:stream_chat/src/extensions/string_extension.dart'; /// Class responsible for uploading images and files to a given channel abstract class AttachmentFileUploader { @@ -57,11 +57,11 @@ abstract class AttachmentFileUploader { /// Stream's default implementation of [AttachmentFileUploader] class StreamAttachmentFileUploader implements AttachmentFileUploader { - final StreamChatClient _client; - /// Creates a new [StreamAttachmentFileUploader] instance. const StreamAttachmentFileUploader(this._client); + final StreamChatClient _client; + @override Future sendImage( AttachmentFile file, @@ -70,16 +70,28 @@ class StreamAttachmentFileUploader implements AttachmentFileUploader { ProgressCallback onSendProgress, CancelToken cancelToken, }) async { - final filename = file.path?.split('/')?.last; + final filename = file.path?.split('/')?.last ?? file.name; final mimeType = filename.mimeType; + + MultipartFile multiPartFile; + if (file.path != null) { + multiPartFile = await MultipartFile.fromFile( + file.path, + filename: filename, + contentType: mimeType, + ); + } else if (file.bytes != null) { + multiPartFile = MultipartFile.fromBytes( + file.bytes, + filename: filename, + contentType: mimeType, + ); + } + final response = await _client.post( '/channels/$channelType/$channelId/image', data: FormData.fromMap({ - 'file': await MultipartFile.fromFile( - file.path, - filename: filename, - contentType: mimeType, - ), + 'file': multiPartFile, }), onSendProgress: onSendProgress, cancelToken: cancelToken, @@ -95,16 +107,28 @@ class StreamAttachmentFileUploader implements AttachmentFileUploader { ProgressCallback onSendProgress, CancelToken cancelToken, }) async { - final filename = file.path?.split('/')?.last; + final filename = file.path?.split('/')?.last ?? file.name; final mimeType = filename.mimeType; + + MultipartFile multiPartFile; + if (file.path != null) { + multiPartFile = await MultipartFile.fromFile( + file.path, + filename: filename, + contentType: mimeType, + ); + } else if (file.bytes != null) { + multiPartFile = MultipartFile.fromBytes( + file.bytes, + filename: filename, + contentType: mimeType, + ); + } + final response = await _client.post( '/channels/$channelType/$channelId/file', data: FormData.fromMap({ - 'file': await MultipartFile.fromFile( - file.path, - filename: filename, - contentType: mimeType, - ), + 'file': multiPartFile, }), onSendProgress: onSendProgress, cancelToken: cancelToken, diff --git a/packages/stream_chat/lib/src/client.dart b/packages/stream_chat/lib/src/client.dart index c5d5322f9..d422dba12 100644 --- a/packages/stream_chat/lib/src/client.dart +++ b/packages/stream_chat/lib/src/client.dart @@ -1,36 +1,34 @@ import 'dart:async'; import 'dart:convert'; +import 'package:stream_chat/src/extensions/map_extension.dart'; import 'package:dio/dio.dart'; import 'package:logging/logging.dart'; import 'package:meta/meta.dart'; -import 'package:pedantic/pedantic.dart' show unawaited; import 'package:rxdart/rxdart.dart'; +import 'package:stream_chat/src/api/channel.dart'; +import 'package:stream_chat/src/api/connection_status.dart'; +import 'package:stream_chat/src/api/requests.dart'; +import 'package:stream_chat/src/api/responses.dart'; import 'package:stream_chat/src/api/retry_policy.dart'; +import 'package:stream_chat/src/api/websocket.dart'; +import 'package:stream_chat/src/attachment_file_uploader.dart'; +import 'package:stream_chat/src/db/chat_persistence_client.dart'; import 'package:stream_chat/src/event_type.dart'; +import 'package:stream_chat/src/exceptions.dart'; import 'package:stream_chat/src/models/attachment_file.dart'; import 'package:stream_chat/src/models/channel_model.dart'; +import 'package:stream_chat/src/models/channel_state.dart'; +import 'package:stream_chat/src/models/event.dart'; +import 'package:stream_chat/src/models/message.dart'; import 'package:stream_chat/src/models/own_user.dart'; +import 'package:stream_chat/src/models/user.dart'; import 'package:stream_chat/src/platform_detector/platform_detector.dart'; import 'package:stream_chat/version.dart'; import 'package:uuid/uuid.dart'; -import 'attachment_file_uploader.dart'; -import 'api/channel.dart'; -import 'api/connection_status.dart'; -import 'api/requests.dart'; -import 'api/responses.dart'; -import 'api/websocket.dart'; -import 'db/chat_persistence_client.dart'; -import 'exceptions.dart'; -import 'models/channel_state.dart'; -import 'models/event.dart'; -import 'models/message.dart'; -import 'models/user.dart'; -import 'extensions/map_extension.dart'; - -/// Handler function used for logging records. Function requires a single [LogRecord] -/// as the only parameter. +/// Handler function used for logging records. Function requires a single +/// [LogRecord] as the only parameter. typedef LogHandlerFunction = void Function(LogRecord record); /// Used for decoding [Map] data to a generic type `T`. @@ -62,7 +60,9 @@ extension on PushProvider { /// The official Dart client for Stream Chat, /// a service for building chat applications. -/// This library can be used on any Dart project and on both mobile and web apps with Flutter. +/// This library can be used on any Dart project and on both mobile and web apps +/// with Flutter. +/// /// You can sign up for a Stream account at https://getstream.io/chat/ /// /// The Chat client will manage API call, event handling and manage the @@ -73,7 +73,8 @@ extension on PushProvider { /// ``` class StreamChatClient { /// Create a client instance with default options. - /// You should only create the client once and re-use it across your application. + /// You should only create the client once and re-use it across your + /// application. StreamChatClient( this.apiKey, { this.tokenProvider, @@ -86,12 +87,14 @@ class StreamChatClient { RetryPolicy retryPolicy, this.attachmentFileUploader, }) { - _retryPolicy ??= RetryPolicy( - retryTimeout: (StreamChatClient client, int attempt, ApiError error) => - Duration(seconds: 1 * attempt), - shouldRetry: (StreamChatClient client, int attempt, ApiError error) => - attempt < 5, - ); + _retryPolicy = retryPolicy ?? + RetryPolicy( + retryTimeout: + (StreamChatClient client, int attempt, ApiError error) => + Duration(seconds: 1 * attempt), + shouldRetry: (StreamChatClient client, int attempt, ApiError error) => + attempt < 5, + ); attachmentFileUploader ??= StreamAttachmentFileUploader(this); @@ -122,30 +125,39 @@ class StreamChatClient { /// This client state ClientState state; - /// By default the Chat client will write all messages with level Warn or Error to stdout. - /// During development you might want to enable more logging information, you can change the default log level when constructing the client. + /// By default the Chat client will write all messages with level Warn or + /// Error to stdout. + /// + /// During development you might want to enable more logging information, + /// you can change the default log level when constructing the client. /// /// ```dart - /// final client = StreamChatClient("stream-chat-api-key", logLevel: Level.INFO); + /// final client = StreamChatClient("stream-chat-api-key", + /// logLevel: Level.INFO); /// ``` final Level logLevel; /// Client specific logger instance. - /// Refer to the class [Logger] to learn more about the specific implementation. + /// Refer to the class [Logger] to learn more about the specific + /// implementation. final Logger logger = Logger.detached('📡'); /// A function that has a parameter of type [LogRecord]. /// This is called on every new log record. - /// By default the client will use the handler returned by [_getDefaultLogHandler]. - /// Setting it 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. + /// By default the client will use the handler returned by + /// [_getDefaultLogHandler]. + /// Setting it 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 /// myLogHandlerFunction = (LogRecord record) { /// // do something with the record (ie. send it to Sentry or Fabric) /// } /// - /// final client = StreamChatClient("stream-chat-api-key", logHandlerFunction: myLogHandlerFunction); + /// final client = StreamChatClient("stream-chat-api-key", + /// logHandlerFunction: myLogHandlerFunction); ///``` LogHandlerFunction logHandlerFunction; @@ -156,14 +168,18 @@ class StreamChatClient { /// Your project Stream Chat base url. final String baseURL; - /// A function in which you send a request to your own backend to get a Stream Chat API token. + /// A function in which you send a request to your own backend to get a Stream + /// Chat API token. + /// /// The token will be the return value of the function. - /// It's used by the client to refresh the token once expired or to connect the user without a predefined token using [connectUserWithProvider]. + /// It's used by the client to refresh the token once expired or to connect + /// the user without a predefined token using [connectUserWithProvider]. final TokenProvider tokenProvider; /// [Dio] httpClient - /// It's be chosen because it's easy to use and supports interesting features out of the box - /// (Interceptors, Global configuration, FormData, File downloading etc.) + /// It's be chosen because it's easy to use and supports interesting features + /// out of the box (Interceptors, Global configuration, FormData, + /// File downloading etc.) @visibleForTesting Dio httpClient = Dio(); @@ -234,7 +250,7 @@ class StreamChatClient { (options.data is Map || options.data == null)) { options.data = { 'connection_id': _connectionId, - ...(options.data ?? {}), + ...options.data ?? {}, }; } @@ -278,7 +294,7 @@ class StreamChatClient { await _disconnect(); final newToken = await tokenProvider(userId); - await Future.delayed(Duration(seconds: 4)); + await Future.delayed(const Duration(seconds: 4)); token = newToken; httpClient.unlock(); @@ -312,7 +328,10 @@ class StreamChatClient { }; return (LogRecord record) { print( - '(${record.time}) ${levelEmojiMapper[record.level.name] ?? record.level.name} ${record.loggerName} ${record.message}'); + '(${record.time}) ' + '${levelEmojiMapper[record.level.name] ?? record.level.name} ' + '${record.loggerName} ${record.message}', + ); if (record.stackTrace != null) { print(record.stackTrace); } @@ -321,11 +340,10 @@ class StreamChatClient { Logger _detachedLogger( String name, - ) { - return Logger.detached(name) - ..level = logLevel - ..onRecord.listen(logHandlerFunction ?? _getDefaultLogHandler()); - } + ) => + Logger.detached(name) + ..level = logLevel + ..onRecord.listen(logHandlerFunction ?? _getDefaultLogHandler()); void _setupLogger() { logger.level = logLevel; @@ -350,7 +368,7 @@ class StreamChatClient { Map get _httpHeaders => { 'Authorization': token, 'stream-auth-type': _authType, - 'x-stream-client': _userAgent, + 'X-Stream-Client': _userAgent, 'Content-Encoding': 'gzip', }; @@ -386,7 +404,8 @@ class StreamChatClient { /// Set the current user using the [tokenProvider] to fetch the token. /// It returns a [Future] that resolves when the connection is setup. @Deprecated( - 'Use `connectUserWithProvider` instead. Will be removed in Future releases') + 'Use `connectUserWithProvider` instead. Will be removed in Future releases', + ) Future setUserWithProvider(User user) => connectUserWithProvider(user); /// Connects the current user using the [tokenProvider] to fetch the token. @@ -470,7 +489,7 @@ class StreamChatClient { 'api_key': apiKey, 'authorization': token, 'stream-auth-type': _authType, - 'x-stream-client': _userAgent, + 'X-Stream-Client': _userAgent, }, connectPayload: { 'user_id': state.user.id, @@ -491,7 +510,8 @@ class StreamChatClient { if (status == ConnectionStatus.connected && state.channels?.isNotEmpty == true) { - unawaited(queryChannelsOnline(filter: { + // ignore: unawaited_futures + queryChannelsOnline(filter: { 'cid': { '\$in': state.channels.keys.toList(), }, @@ -503,7 +523,7 @@ class StreamChatClient { online: true, )); }, - )); + ); } else { _synced = false; } @@ -521,6 +541,7 @@ class StreamChatClient { }).catchError((err, stacktrace) { logger.severe('error connecting ws', err, stacktrace); if (err is Map) { + // ignore: only_throw_errors throw err; } }); @@ -558,13 +579,12 @@ class StreamChatClient { res.events.sort((a, b) => a.createdAt.compareTo(b.createdAt)); res.events.forEach((element) { - logger.fine('element.type: ${element.type}'); - logger.fine('element.message.text: ${element.message?.text}'); + logger + ..fine('element.type: ${element.type}') + ..fine('element.message.text: ${element.message?.text}'); }); - res.events.forEach((event) { - handleEvent(event); - }); + res.events.forEach(handleEvent); await chatPersistenceClient?.updateLastSyncAt(DateTime.now()); _synced = true; @@ -573,9 +593,7 @@ class StreamChatClient { } } - String _asMap(sort) { - return sort?.map((s) => s.toJson().toString())?.join(''); - } + String _asMap(sort) => sort?.map((s) => s.toJson().toString())?.join(''); final _queryChannelsStreams = >>{}; @@ -584,40 +602,41 @@ class StreamChatClient { Map filter, List> sort, Map options, - PaginationParams paginationParams = const PaginationParams(limit: 10), + PaginationParams paginationParams = const PaginationParams(), int messageLimit, - bool preferOffline = false, bool waitForConnect = true, }) async* { final hash = base64.encode(utf8.encode( - '$filter${_asMap(sort)}$options${paginationParams?.toJson()}$messageLimit$preferOffline', + '$filter${_asMap(sort)}$options${paginationParams?.toJson()}' + '$messageLimit', )); if (_queryChannelsStreams.containsKey(hash)) { yield await _queryChannelsStreams[hash]; } else { - if (preferOffline) { - final channels = await queryChannelsOffline( - filter: filter, - sort: sort, - paginationParams: paginationParams, - ); - if (channels.isNotEmpty) yield channels; - } - - final newQueryChannelsFuture = queryChannelsOnline( + final channels = await queryChannelsOffline( filter: filter, sort: sort, - options: options, paginationParams: paginationParams, - messageLimit: messageLimit, - ).whenComplete(() { - _queryChannelsStreams.remove(hash); - }); + ); + if (channels.isNotEmpty) yield channels; + + if (wsConnectionStatus == ConnectionStatus.connected) { + final newQueryChannelsFuture = queryChannelsOnline( + filter: filter, + sort: sort, + options: options, + paginationParams: paginationParams, + messageLimit: messageLimit, + waitForConnect: waitForConnect, + ).whenComplete(() { + _queryChannelsStreams.remove(hash); + }); - _queryChannelsStreams[hash] = newQueryChannelsFuture; + _queryChannelsStreams[hash] = newQueryChannelsFuture; - yield await newQueryChannelsFuture; + yield await newQueryChannelsFuture; + } } } @@ -627,7 +646,7 @@ class StreamChatClient { List> sort, Map options, int messageLimit, - PaginationParams paginationParams = const PaginationParams(limit: 10), + PaginationParams paginationParams = const PaginationParams(), bool waitForConnect = true, }) async { if (waitForConnect) { @@ -650,7 +669,7 @@ class StreamChatClient { 'presence': false, }; - var payload = { + final payload = { 'filter_conditions': filter, 'sort': sort, }; @@ -682,9 +701,12 @@ class StreamChatClient { ); if ((res.channels ?? []).isEmpty && (paginationParams?.offset ?? 0) == 0) { - logger.warning('''We could not find any channel for this query. + logger.warning( + ''' + We could not find any channel for this query. Please make sure to take a look at the Flutter tutorial: https://getstream.io/chat/flutter/tutorial - If your application already has users and channels, you might need to adjust your query channel as explained in the docs https://getstream.io/chat/docs/query_channels/?language=dart'''); + If your application already has users and channels, you might need to adjust your query channel as explained in the docs https://getstream.io/chat/docs/query_channels/?language=dart''', + ); return []; } @@ -715,7 +737,7 @@ class StreamChatClient { Future> queryChannelsOffline({ @required Map filter, @required List> sort, - PaginationParams paginationParams = const PaginationParams(limit: 10), + PaginationParams paginationParams = const PaginationParams(), }) async { final offlineChannels = await chatPersistenceClient?.getChannelStates( filter: filter, @@ -771,6 +793,7 @@ class StreamChatClient { ); return response; } on DioError catch (error) { + // ignore: only_throw_errors throw _parseError(error); } } @@ -791,6 +814,7 @@ class StreamChatClient { ); return response; } on DioError catch (error) { + // ignore: only_throw_errors throw _parseError(error); } } @@ -809,6 +833,7 @@ class StreamChatClient { ); return response; } on DioError catch (error) { + // ignore: only_throw_errors throw _parseError(error); } } @@ -827,6 +852,7 @@ class StreamChatClient { ); return response; } on DioError catch (error) { + // ignore: only_throw_errors throw _parseError(error); } } @@ -845,6 +871,7 @@ class StreamChatClient { ); return response; } on DioError catch (error) { + // ignore: only_throw_errors throw _parseError(error); } } @@ -864,8 +891,8 @@ class StreamChatClient { String get _authType => _anonymous ? 'anonymous' : 'jwt'; - String get _userAgent => - 'stream-chat-dart-client-${CurrentPlatform.name}-${PACKAGE_VERSION.split('+')[0]}'; + String get _userAgent => 'stream-chat-dart-client-${CurrentPlatform.name}-' + '${PACKAGE_VERSION.split('+')[0]}'; Map get _commonQueryParams => { 'user_id': state.user?.id, @@ -873,14 +900,15 @@ class StreamChatClient { 'connection_id': _connectionId, }; - /// Set the current user with an anonymous id, this triggers a connection to the API. - /// It returns a [Future] that resolves when the connection is setup. + /// Set the current user with an anonymous id, this triggers a connection to + /// the API. It returns a [Future] that resolves when the connection is setup. @Deprecated( 'Use `connectAnonymousUser` instead. Will be removed in Future releases') Future setAnonymousUser() => connectAnonymousUser(); - /// Connects the current user with an anonymous id, this triggers a connection to the API. - /// It returns a [Future] that resolves when the connection is setup. + /// Connects the current user with an anonymous id, this triggers a connection + /// to the API. It returns a [Future] that resolves when the connection is + /// setup. Future connectAnonymousUser() async { if (_connectCompleter != null && !_connectCompleter.isCompleted) { logger.warning('Already connecting'); @@ -923,14 +951,14 @@ class StreamChatClient { } /// Closes the websocket connection and resets the client - /// If [flushChatPersistence] is true the client deletes all offline user's data - /// If [clearUser] is true the client unsets the current user + /// If [flushChatPersistence] is true the client deletes all offline + /// user's data. If [clearUser] is true the client unsets the current user Future disconnect({ bool flushChatPersistence = false, bool clearUser = false, }) async { - logger.info( - 'Disconnecting flushOfflineStorage: $flushChatPersistence; clearUser: $clearUser'); + logger.info('Disconnecting flushOfflineStorage: $flushChatPersistence; ' + 'clearUser: $clearUser'); await chatPersistenceClient?.disconnect(flush: flushChatPersistence); chatPersistenceClient = null; @@ -966,9 +994,7 @@ class StreamChatClient { final payload = { 'filter_conditions': filter ?? {}, 'sort': sort, - }; - - payload.addAll(defaultOptions); + }..addAll(defaultOptions); if (pagination != null) { payload.addAll(pagination.toJson()); @@ -1016,7 +1042,7 @@ class StreamChatClient { ); } return true; - }()); + }(), 'Check incoming params.'); final payload = { 'filter_conditions': filters, @@ -1041,15 +1067,14 @@ class StreamChatClient { String channelType, { ProgressCallback onSendProgress, CancelToken cancelToken, - }) { - return attachmentFileUploader.sendFile( - file, - channelId, - channelType, - onSendProgress: onSendProgress, - cancelToken: cancelToken, - ); - } + }) => + attachmentFileUploader.sendFile( + file, + channelId, + channelType, + onSendProgress: onSendProgress, + cancelToken: cancelToken, + ); /// Send a [image] to the [channelId] of type [channelType] Future sendImage( @@ -1058,15 +1083,14 @@ class StreamChatClient { String channelType, { ProgressCallback onSendProgress, CancelToken cancelToken, - }) { - return attachmentFileUploader.sendImage( - image, - channelId, - channelType, - onSendProgress: onSendProgress, - cancelToken: cancelToken, - ); - } + }) => + attachmentFileUploader.sendImage( + image, + channelId, + channelType, + onSendProgress: onSendProgress, + cancelToken: cancelToken, + ); /// Delete a file from this channel Future deleteFile( @@ -1074,14 +1098,13 @@ class StreamChatClient { String channelId, String channelType, { CancelToken cancelToken, - }) { - return attachmentFileUploader.deleteFile( - url, - channelId, - channelType, - cancelToken: cancelToken, - ); - } + }) => + attachmentFileUploader.deleteFile( + url, + channelId, + channelType, + cancelToken: cancelToken, + ); /// Delete an image from this channel Future deleteImage( @@ -1089,14 +1112,13 @@ class StreamChatClient { String channelId, String channelType, { CancelToken cancelToken, - }) { - return attachmentFileUploader.deleteImage( - url, - channelId, - channelType, - cancelToken: cancelToken, - ); - } + }) => + attachmentFileUploader.deleteImage( + url, + channelId, + channelType, + cancelToken: cancelToken, + ); /// Add a device for Push Notifications. Future addDevice(String id, PushProvider pushProvider) async { @@ -1146,9 +1168,8 @@ class StreamChatClient { } /// Update or Create the given user object. - Future updateUser(User user) async { - return updateUsers([user]); - } + Future updateUser(User user) async => + updateUsers([user]); /// Batch update a list of users Future updateUsers(List users) async { @@ -1197,23 +1218,21 @@ class StreamChatClient { Future shadowBan( String targetID, [ Map options = const {}, - ]) async { - return banUser(targetID, { - 'shadow': true, - ...options, - }); - } + ]) async => + banUser(targetID, { + 'shadow': true, + ...options, + }); /// Removes shadow ban from a user Future removeShadowBan( String targetID, [ Map options = const {}, - ]) async { - return unbanUser(targetID, { - 'shadow': true, - ...options, - }); - } + ]) async => + unbanUser(targetID, { + 'shadow': true, + ...options, + }); /// Mutes a user Future muteUser(String targetID) async { @@ -1312,7 +1331,7 @@ class StreamChatClient { throw ArgumentError('Invalid timeout or Expiration date'); } return true; - }()); + }(), 'Check whether time out is valid'); DateTime pinExpires; if (timeoutOrExpirationDate is DateTime) { @@ -1328,15 +1347,12 @@ class StreamChatClient { } /// Unpins provided message - Future unpinMessage(Message message) { - return updateMessage(message.copyWith(pinned: false)); - } + Future unpinMessage(Message message) => + updateMessage(message.copyWith(pinned: false)); } /// The class that handles the state of the channel listening to the events class ClientState { - final _subscriptions = []; - /// Creates a new instance listening to events and updating the state ClientState(this._client) { _subscriptions.addAll([ @@ -1358,16 +1374,12 @@ class ClientState { .on() .where((event) => event.unreadChannels != null) .map((e) => e.unreadChannels) - .listen((unreadChannels) { - _unreadChannelsController.add(unreadChannels); - }), + .listen(_unreadChannelsController.add), _client .on() .where((event) => event.totalUnreadCount != null) .map((e) => e.totalUnreadCount) - .listen((totalUnreadCount) { - _totalUnreadCountController.add(totalUnreadCount); - }), + .listen(_totalUnreadCountController.add), ]); _listenChannelDeleted(); @@ -1377,6 +1389,8 @@ class ClientState { _listenUserUpdated(); } + final _subscriptions = []; + /// Used internally for optimistic update of unread count set totalUnreadCount(int unreadCount) { _totalUnreadCountController?.add(unreadCount ?? 0); diff --git a/packages/stream_chat/lib/src/db/chat_persistence_client.dart b/packages/stream_chat/lib/src/db/chat_persistence_client.dart index da99f34e4..d90872a2f 100644 --- a/packages/stream_chat/lib/src/db/chat_persistence_client.dart +++ b/packages/stream_chat/lib/src/db/chat_persistence_client.dart @@ -101,18 +101,17 @@ abstract class ChatPersistenceClient { Future updateChannelQueries( Map filter, List cids, + // ignore: avoid_positional_boolean_parameters bool clearQueryCache, ); /// Remove a message by [messageId] - Future deleteMessageById(String messageId) { - return deleteMessageByIds([messageId]); - } + Future deleteMessageById(String messageId) => + deleteMessageByIds([messageId]); /// Remove a pinned message by [messageId] - Future deletePinnedMessageById(String messageId) { - return deletePinnedMessageByIds([messageId]); - } + Future deletePinnedMessageById(String messageId) => + deletePinnedMessageByIds([messageId]); /// Remove a message by [messageIds] Future deleteMessageByIds(List messageIds); @@ -121,14 +120,11 @@ abstract class ChatPersistenceClient { Future deletePinnedMessageByIds(List messageIds); /// Remove a message by channel [cid] - Future deleteMessageByCid(String cid) { - return deleteMessageByCids([cid]); - } + Future deleteMessageByCid(String cid) => deleteMessageByCids([cid]); /// Remove a pinned message by channel [cid] - Future deletePinnedMessageByCid(String cid) { - return deletePinnedMessageByCids([cid]); - } + Future deletePinnedMessageByCid(String cid) async => + deletePinnedMessageByCids([cid]); /// Remove a message by message [cids] Future deleteMessageByCids(List cids); @@ -175,9 +171,8 @@ abstract class ChatPersistenceClient { Future deleteMembersByCids(List cids); /// Update the channel state data using [channelState] - Future updateChannelState(ChannelState channelState) { - return updateChannelStates([channelState]); - } + Future updateChannelState(ChannelState channelState) => + updateChannelStates([channelState]); /// Update list of channel states Future updateChannelStates(List channelStates) async { @@ -195,31 +190,31 @@ abstract class ChatPersistenceClient { deleteMembers, ]); - final channels = channelStates.map((it) { - return it.channel; - }).where((it) => it != null); + final channels = + channelStates.map((it) => it.channel).where((it) => it != null); - final reactions = channelStates.expand((it) => it.messages).expand((it) { - return [ - if (it.ownReactions != null) - ...it.ownReactions.where((r) => r.userId != null), - if (it.latestReactions != null) - ...it.latestReactions.where((r) => r.userId != null) - ]; - }).where((it) => it != null); + final reactions = channelStates + .expand((it) => it.messages) + .expand((it) => [ + if (it.ownReactions != null) + ...it.ownReactions.where((r) => r.userId != null), + if (it.latestReactions != null) + ...it.latestReactions.where((r) => r.userId != null) + ]) + .where((it) => it != null); final users = channelStates .map((cs) => [ cs.channel?.createdBy, - ...cs.messages?.map((m) { - return [ - m.user, - if (m.latestReactions != null) - ...m.latestReactions.map((r) => r.user), - if (m.ownReactions != null) - ...m.ownReactions.map((r) => r.user), - ]; - })?.expand((v) => v), + ...cs.messages + ?.map((m) => [ + m.user, + if (m.latestReactions != null) + ...m.latestReactions.map((r) => r.user), + if (m.ownReactions != null) + ...m.ownReactions.map((r) => r.user), + ]) + ?.expand((v) => v), if (cs.read != null) ...cs.read.map((r) => r.user), if (cs.members != null) ...cs.members.map((m) => m.user), ]) diff --git a/packages/stream_chat/lib/src/debounce.dart b/packages/stream_chat/lib/src/debounce.dart deleted file mode 100644 index f1cf05a45..000000000 --- a/packages/stream_chat/lib/src/debounce.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'dart:async'; - -import 'package:meta/meta.dart'; - -/// Map of timeouts being debounced -Map timeouts = {}; - -/// Runs a function avoiding calling it too many times in a [timeoutMS] window -void debounce({ - @required Duration timeout, - @required Function target, - List positionalArguments, - Map namedArguments, -}) { - if (timeouts.containsKey(target)) { - timeouts[target].cancel(); - } - - final timer = Timer(timeout, () { - Function.apply( - target, - positionalArguments, - namedArguments, - ); - }); - - timeouts[target] = timer; -} diff --git a/packages/stream_chat/lib/src/exceptions.dart b/packages/stream_chat/lib/src/exceptions.dart index 9ba27e795..60dd6bdff 100644 --- a/packages/stream_chat/lib/src/exceptions.dart +++ b/packages/stream_chat/lib/src/exceptions.dart @@ -2,6 +2,13 @@ import 'dart:convert'; /// Exception related to api calls class ApiError extends Error { + /// Creates a new ApiError instance using the response body and status code + ApiError(this.body, this.status) : jsonData = _decode(body) { + if (jsonData != null && jsonData.containsKey('code')) { + _code = jsonData['code']; + } + } + /// Raw body of the response final String body; @@ -26,13 +33,6 @@ class ApiError extends Error { } } - /// Creates a new ApiError instance using the response body and status code - ApiError(this.body, this.status) : jsonData = _decode(body) { - if (jsonData != null && jsonData.containsKey('code')) { - _code = jsonData['code']; - } - } - @override bool operator ==(Object other) => identical(this, other) || @@ -48,7 +48,6 @@ class ApiError extends Error { body.hashCode ^ jsonData.hashCode ^ status.hashCode ^ _code.hashCode; @override - String toString() { - return 'ApiError{body: $body, jsonData: $jsonData, status: $status, code: $_code}'; - } + String toString() => 'ApiError{body: $body, jsonData: $jsonData, ' + 'status: $status, code: $_code}'; } diff --git a/packages/stream_chat/lib/src/extensions/map_extension.dart b/packages/stream_chat/lib/src/extensions/map_extension.dart index 3028c20a2..1a3376ad2 100644 --- a/packages/stream_chat/lib/src/extensions/map_extension.dart +++ b/packages/stream_chat/lib/src/extensions/map_extension.dart @@ -1,7 +1,6 @@ /// Useful extension functions for [Map] extension MapX on Map { /// Returns a new map with null keys or values removed - Map get nullProtected { - return {...this}..removeWhere((key, value) => key == null || value == null); - } + Map get nullProtected => + {...this}..removeWhere((key, value) => key == null || value == null); } diff --git a/packages/stream_chat/lib/src/extensions/rate_limit.dart b/packages/stream_chat/lib/src/extensions/rate_limit.dart new file mode 100644 index 000000000..c9f5934fb --- /dev/null +++ b/packages/stream_chat/lib/src/extensions/rate_limit.dart @@ -0,0 +1,335 @@ +// ignore_for_file: lines_longer_than_80_chars + +import 'dart:async' show Timer; +import 'dart:math' as math; + +/// Useful rate limiter extensions for [Function] class. +extension RateLimit on Function { + /// Converts this into a [Debounce] function. + Debounce debounced( + Duration wait, { + bool leading = false, + bool trailing = true, + Duration maxWait, + }) => + Debounce( + this, + wait, + leading: leading, + trailing: trailing, + maxWait: maxWait, + ); + + /// Converts this into a [Throttle] function. + Throttle throttled( + Duration wait, { + bool leading = true, + bool trailing = true, + }) => + Throttle( + this, + wait, + leading: leading, + trailing: trailing, + ); +} + +/// TopLevel lambda to create [Debounce] functions. +Debounce debounce( + Function func, + Duration wait, { + bool leading = false, + bool trailing = true, + Duration maxWait, +}) => + Debounce( + func, + wait, + leading: leading, + trailing: trailing, + maxWait: maxWait, + ); + +/// TopLevel lambda to create [Throttle] functions. +Throttle throttle( + Function func, + Duration wait, { + bool leading = true, + bool trailing = true, +}) => + Throttle( + func, + wait, + leading: leading, + trailing: trailing, + ); + +/// Creates a debounced function that delays invoking `func` until after `wait` +/// milliseconds have elapsed since the last time the debounced function was +/// invoked. The debounced function comes with a [Debounce.cancel] method to cancel +/// delayed `func` invocations and a [Debounce.flush] method to immediately invoke them. +/// Provide `leading` and/or `trailing` to indicate whether `func` should be +/// invoked on the `leading` and/or `trailing` edge of the `wait` interval. +/// The `func` is invoked with the last arguments provided to the [call] +/// function. Subsequent calls to the debounced function return the result of +/// the last `func` invocation. +/// +/// **Note:** If `leading` and `trailing` options are `true`, `func` is +/// invoked on the trailing edge of the timeout only if the debounced function +/// is invoked more than once during the `wait` timeout. +/// +/// If `wait` is [Duration.zero] and `leading` is `false`, +/// `func` invocation is deferred until the next tick. +/// +/// See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) +/// for details over the differences between [Debounce] and [Throttle]. +/// +/// Some examples: +/// +/// Avoid calling costly network calls when user is typing something. +/// ```dart +/// void fetchData(String query) async { +/// final data = api.getData(query); +/// doSomethingWithTheData(data); +/// } +/// +/// final debouncedFetchData = Debounce( +/// fetchData, +/// const Duration(milliseconds: 350), +/// ); +/// +/// void onSearchQueryChanged(query) { +/// debouncedFetchData(query); +/// } +/// ``` +/// +/// Cancel the trailing debounced invocation. +/// ```dart +/// void dispose() { +/// debounced.cancel(); +/// } +/// ``` +/// +/// Check for pending invocations. +/// ```dart +/// final status = debounced.isPending ? "Pending..." : "Ready"; +/// ``` +class Debounce { + /// Creates a new instance of [Debounce]. + Debounce( + this._func, + Duration wait, { + bool leading = false, + bool trailing = true, + Duration maxWait, + }) : _leading = leading, + _trailing = trailing, + _wait = wait?.inMilliseconds ?? 0, + _maxing = maxWait != null { + if (_maxing) { + _maxWait = math.max(maxWait.inMilliseconds, _wait); + } + } + + final Function _func; + final bool _leading; + final bool _trailing; + final int _wait; + final bool _maxing; + + int _maxWait; + List _lastArgs; + Map _lastNamedArgs; + Timer _timer; + int _lastCallTime; + Object _result; + int _lastInvokeTime = 0; + + Object _invokeFunc(int time) { + final args = _lastArgs; + final namedArgs = _lastNamedArgs; + _lastArgs = _lastNamedArgs = null; + _lastInvokeTime = time; + return _result = Function.apply(_func, args, namedArgs); + } + + Timer _startTimer(Function pendingFunc, int wait) => + Timer(Duration(milliseconds: wait), pendingFunc); + + bool _shouldInvoke(int time) { + final timeSinceLastCall = time - (_lastCallTime ?? double.nan); + final timeSinceLastInvoke = time - _lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return _lastCallTime == null || + (timeSinceLastCall >= _wait) || + (timeSinceLastCall < 0) || + (_maxing && timeSinceLastInvoke >= _maxWait); + } + + Object _trailingEdge(int time) { + _timer = null; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (_trailing && _lastArgs != null) { + return _invokeFunc(time); + } + _lastArgs = _lastNamedArgs = null; + return _result; + } + + int _remainingWait(int time) { + final timeSinceLastCall = time - _lastCallTime; + final timeSinceLastInvoke = time - _lastInvokeTime; + final timeWaiting = _wait - timeSinceLastCall; + + return _maxing + ? math.min(timeWaiting, _maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + void _timerExpired() { + final time = DateTime.now().millisecondsSinceEpoch; + if (_shouldInvoke(time)) { + _trailingEdge(time); + } else { + // Restart the timer. + _timer = _startTimer(_timerExpired, _remainingWait(time)); + } + } + + Object _leadingEdge(int time) { + // Reset any `maxWait` timer. + _lastInvokeTime = time; + // Start the timer for the trailing edge. + _timer = _startTimer(_timerExpired, _wait); + // Invoke the leading edge. + return _leading ? _invokeFunc(time) : _result; + } + + /// Cancels all the remaining delayed functions. + void cancel() { + _timer?.cancel(); + _lastInvokeTime = 0; + _lastArgs = _lastNamedArgs = _lastCallTime = _timer = null; + } + + /// Immediately invokes all the remaining delayed functions. + Object flush() { + final now = DateTime.now().millisecondsSinceEpoch; + return _timer == null ? _result : _trailingEdge(now); + } + + /// True if there are functions remaining to get invoked. + bool get isPending => _timer != null; + + /// Calls/invokes this class like a function. + /// Pass [args] and [namedArgs] to be used while invoking [_func]. + Object call( + List args, { + Map namedArgs, + }) { + final time = DateTime.now().millisecondsSinceEpoch; + final isInvoking = _shouldInvoke(time); + + _lastArgs = args; + _lastNamedArgs = namedArgs; + _lastCallTime = time; + + if (isInvoking) { + if (_timer == null) { + return _leadingEdge(_lastCallTime); + } + if (_maxing) { + // Handle invocations in a tight loop. + _timer = _startTimer(_timerExpired, _wait); + return _invokeFunc(_lastCallTime); + } + } + _timer ??= _startTimer(_timerExpired, _wait); + return _result; + } +} + +/// Creates a throttled function that only invokes `func` at most once per +/// every `wait` milliseconds. The throttled function comes with a [Throttle.cancel] +/// method to cancel delayed `func` invocations and a [Throttle.flush] method to +/// immediately invoke them. Provide `leading` and/or `trailing` to indicate +/// whether `func` should be invoked on the `leading` and/or `trailing` edge of the `wait` timeout. +/// The `func` is invoked with the last arguments provided to the +/// throttled function. Subsequent calls to the throttled function return the +/// result of the last `func` invocation. +/// +/// **Note:** If `leading` and `trailing` options are `true`, `func` is +/// invoked on the trailing edge of the timeout only if the throttled function +/// is invoked more than once during the `wait` timeout. +/// +/// If `wait` is [Duration.zero] and `leading` is `false`, `func` invocation is deferred +/// until the next tick. +/// +/// See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) +/// for details over the differences between [Throttle] and [Debounce]. +/// +/// Some examples: +/// +/// Avoid excessively rebuilding UI progress while uploading data to server. +/// ```dart +/// void updateUI(Data data) { +/// updateProgress(data); +/// } +/// +/// final throttledUpdateUI = Throttle( +/// updateUI, +/// const Duration(milliseconds: 350), +/// ); +/// +/// void onUploadProgressChanged(progress) { +/// throttledUpdateUI(progress); +/// } +/// ``` +/// +/// Cancel the trailing throttled invocation. +/// ```dart +/// void dispose() { +/// throttled.cancel(); +/// } +/// ``` +/// +/// Check for pending invocations. +/// ```dart +/// final status = throttled.isPending ? "Pending..." : "Ready"; +/// ``` +class Throttle { + /// Creates a new instance of [Throttle] + Throttle( + Function func, + Duration wait, { + bool leading = true, + bool trailing = true, + }) : _debounce = Debounce( + func, + wait, + leading: leading, + trailing: trailing, + maxWait: wait, + ); + + final Debounce _debounce; + + /// Cancels all the remaining delayed functions. + void cancel() => _debounce.cancel(); + + /// Immediately invokes all the remaining delayed functions. + Object flush() => _debounce.flush(); + + /// True if there are functions remaining to get invoked. + bool get isPending => _debounce.isPending; + + /// Calls/invokes this class like a function. + /// Pass [args] and [namedArgs] to be used while invoking `func`. + Object call(List args, {Map namedArgs}) => + _debounce.call(args, namedArgs: namedArgs); +} diff --git a/packages/stream_chat/lib/src/models/action.dart b/packages/stream_chat/lib/src/models/action.dart index 34bb8f7e5..62d0f104f 100644 --- a/packages/stream_chat/lib/src/models/action.dart +++ b/packages/stream_chat/lib/src/models/action.dart @@ -5,6 +5,12 @@ part 'action.g.dart'; /// The class that contains the information about an action @JsonSerializable() class Action { + /// Constructor used for json serialization + Action({this.name, this.style, this.text, this.type, this.value}); + + /// Create a new instance from a json + factory Action.fromJson(Map json) => _$ActionFromJson(json); + /// The name of the action final String name; @@ -20,12 +26,6 @@ class Action { /// The value of the action final String value; - /// Constructor used for json serialization - Action({this.name, this.style, this.text, this.type, this.value}); - - /// Create a new instance from a json - factory Action.fromJson(Map json) => _$ActionFromJson(json); - /// Serialize to json Map toJson() => _$ActionToJson(this); } diff --git a/packages/stream_chat/lib/src/models/attachment.dart b/packages/stream_chat/lib/src/models/attachment.dart index e2e81cd93..de5149db2 100644 --- a/packages/stream_chat/lib/src/models/attachment.dart +++ b/packages/stream_chat/lib/src/models/attachment.dart @@ -1,18 +1,61 @@ // ignore_for_file: public_member_api_docs import 'package:json_annotation/json_annotation.dart'; +import 'package:stream_chat/src/models/action.dart'; import 'package:stream_chat/src/models/attachment_file.dart'; +import 'package:stream_chat/src/models/serialization.dart'; import 'package:uuid/uuid.dart'; -import 'action.dart'; -import 'serialization.dart'; - part 'attachment.g.dart'; /// The class that contains the information about an attachment @JsonSerializable(includeIfNull: false) class Attachment { - ///The attachment type based on the URL resource. This can be: audio, image or video + /// Constructor used for json serialization + Attachment({ + String id, + this.type, + this.titleLink, + String title, + this.thumbUrl, + this.text, + this.pretext, + this.ogScrapeUrl, + this.imageUrl, + this.footerIcon, + this.footer, + this.fields, + this.fallback, + this.color, + this.authorName, + this.authorLink, + this.authorIcon, + this.assetUrl, + this.actions, + this.extraData, + this.file, + UploadState uploadState, + }) : id = id ?? Uuid().v4(), + title = title ?? file?.name, + localUri = file?.path != null ? Uri.parse(file.path) : null { + this.uploadState = uploadState ?? + ((assetUrl != null || imageUrl != null) + ? const UploadState.success() + : const UploadState.preparing()); + } + + /// Create a new instance from a json + factory Attachment.fromJson(Map json) => + _$AttachmentFromJson( + Serialization.moveToExtraDataFromRoot(json, topLevelFields)); + + /// Create a new instance from a db data + factory Attachment.fromData(Map json) => + _$AttachmentFromJson(Serialization.moveToExtraDataFromRoot( + json, topLevelFields + dbSpecificTopLevelFields)); + + ///The attachment type based on the URL resource. This can be: audio, + ///image or video final String type; ///The link to which the attachment message points to. @@ -21,10 +64,12 @@ class Attachment { /// The attachment title final String title; - /// The URL to the attached file thumbnail. You can use this to represent the attached link. + /// The URL to the attached file thumbnail. You can use this to represent the + /// attached link. final String thumbUrl; - /// The attachment text. It will be displayed in the channel next to the original message. + /// The attachment text. It will be displayed in the channel next to the + /// original message. final String text; /// Optional text that appears above the attachment block @@ -33,7 +78,8 @@ class Attachment { /// The original URL that was used to scrape this attachment. final String ogScrapeUrl; - /// The URL to the attached image. This is present for URL pointing to an image article (eg. Unsplash) + /// The URL to the attached image. This is present for URL pointing to an + /// image article (eg. Unsplash) final String imageUrl; final String footerIcon; final String footer; @@ -100,56 +146,11 @@ class Attachment { 'file', ]; - /// Constructor used for json serialization - Attachment({ - String id, - this.type, - this.titleLink, - String title, - this.thumbUrl, - this.text, - this.pretext, - this.ogScrapeUrl, - this.imageUrl, - this.footerIcon, - this.footer, - this.fields, - this.fallback, - this.color, - this.authorName, - this.authorLink, - this.authorIcon, - this.assetUrl, - this.actions, - this.extraData, - this.file, - UploadState uploadState, - }) : id = id ?? Uuid().v4(), - title = title ?? file?.name, - localUri = file?.path != null ? Uri.parse(file.path) : null { - this.uploadState = uploadState ?? - ((assetUrl != null || imageUrl != null) - ? UploadState.success() - : UploadState.preparing()); - } - - /// Create a new instance from a json - factory Attachment.fromJson(Map json) { - return _$AttachmentFromJson( - Serialization.moveToExtraDataFromRoot(json, topLevelFields)); - } - /// Serialize to json Map toJson() => Serialization.moveFromExtraDataToRoot( _$AttachmentToJson(this), topLevelFields) ..removeWhere((key, value) => dbSpecificTopLevelFields.contains(key)); - /// Create a new instance from a db data - factory Attachment.fromData(Map json) { - return _$AttachmentFromJson(Serialization.moveToExtraDataFromRoot( - json, topLevelFields + dbSpecificTopLevelFields)); - } - /// Serialize to db data Map toData() => Serialization.moveFromExtraDataToRoot( _$AttachmentToJson(this), topLevelFields + dbSpecificTopLevelFields); diff --git a/packages/stream_chat/lib/src/models/attachment_file.dart b/packages/stream_chat/lib/src/models/attachment_file.dart index f1c10d5ca..bae7810f1 100644 --- a/packages/stream_chat/lib/src/models/attachment_file.dart +++ b/packages/stream_chat/lib/src/models/attachment_file.dart @@ -1,10 +1,9 @@ import 'dart:typed_data'; -import 'package:meta/meta.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:meta/meta.dart'; part 'attachment_file.freezed.dart'; - part 'attachment_file.g.dart'; /// Union class to hold various [UploadState] of a attachment. @@ -57,8 +56,12 @@ class AttachmentFile { this.size, }); - /// The absolute path for a cached copy of this file. It can be used to create a - /// file instance with a descriptor for the given path. + /// Create a new instance from a json + factory AttachmentFile.fromJson(Map json) => + _$AttachmentFileFromJson(json); + + /// The absolute path for a cached copy of this file. It can be used to + /// create a file instance with a descriptor for the given path. /// ``` /// final File myFile = File(platformFile.path); /// ``` @@ -67,8 +70,8 @@ class AttachmentFile { /// File name including its extension. final String name; - /// Byte data for this file. Particularly useful if you want to manipulate its data - /// or easily upload to somewhere else. + /// Byte data for this file. Particularly useful if you want to manipulate + /// its data or easily upload to somewhere else. @JsonKey(toJson: _toString, fromJson: _fromString) final Uint8List bytes; @@ -78,11 +81,6 @@ class AttachmentFile { /// File extension for this file. String get extension => name?.split('.')?.last; - /// Create a new instance from a json - factory AttachmentFile.fromJson(Map json) { - return _$AttachmentFileFromJson(json); - } - /// Serialize to json Map toJson() => _$AttachmentFileToJson(this); } diff --git a/packages/stream_chat/lib/src/models/channel_config.dart b/packages/stream_chat/lib/src/models/channel_config.dart index e455930f1..3541573e9 100644 --- a/packages/stream_chat/lib/src/models/channel_config.dart +++ b/packages/stream_chat/lib/src/models/channel_config.dart @@ -1,12 +1,34 @@ import 'package:json_annotation/json_annotation.dart'; - -import 'command.dart'; - +import 'package:stream_chat/src/models/command.dart'; part 'channel_config.g.dart'; /// The class that contains the information about the configuration of a channel @JsonSerializable() class ChannelConfig { + /// Constructor used for json serialization + ChannelConfig({ + this.automod, + this.commands, + this.connectEvents, + this.createdAt, + this.updatedAt, + this.maxMessageLength, + this.messageRetention, + this.mutes, + this.name, + this.reactions, + this.readEvents, + this.replies, + this.search, + this.typingEvents, + this.uploads, + this.urlEnrichment, + }); + + /// Create a new instance from a json + factory ChannelConfig.fromJson(Map json) => + _$ChannelConfigFromJson(json); + /// Moderation configuration final String automod; @@ -55,30 +77,6 @@ class ChannelConfig { /// True if urls appears as attachments final bool urlEnrichment; - /// Constructor used for json serialization - ChannelConfig({ - this.automod, - this.commands, - this.connectEvents, - this.createdAt, - this.updatedAt, - this.maxMessageLength, - this.messageRetention, - this.mutes, - this.name, - this.reactions, - this.readEvents, - this.replies, - this.search, - this.typingEvents, - this.uploads, - this.urlEnrichment, - }); - - /// Create a new instance from a json - factory ChannelConfig.fromJson(Map json) => - _$ChannelConfigFromJson(json); - /// Serialize to json Map toJson() => _$ChannelConfigToJson(this); } diff --git a/packages/stream_chat/lib/src/models/channel_model.dart b/packages/stream_chat/lib/src/models/channel_model.dart index 046e29c57..62ea18535 100644 --- a/packages/stream_chat/lib/src/models/channel_model.dart +++ b/packages/stream_chat/lib/src/models/channel_model.dart @@ -1,14 +1,35 @@ import 'package:json_annotation/json_annotation.dart'; - -import 'channel_config.dart'; -import 'serialization.dart'; -import 'user.dart'; +import 'package:stream_chat/src/models/channel_config.dart'; +import 'package:stream_chat/src/models/serialization.dart'; +import 'package:stream_chat/src/models/user.dart'; part 'channel_model.g.dart'; /// The class that contains the information about a channel @JsonSerializable() class ChannelModel { + /// Constructor used for json serialization + ChannelModel({ + this.id, + this.type, + this.cid, + this.config, + this.createdBy, + this.frozen, + this.lastMessageAt, + this.createdAt, + this.updatedAt, + this.deletedAt, + this.memberCount, + this.extraData, + this.team, + }); + + /// Create a new instance from a json + factory ChannelModel.fromJson(Map json) => + _$ChannelModelFromJson( + Serialization.moveToExtraDataFromRoot(json, topLevelFields)); + /// The id of this channel final String id; @@ -76,40 +97,15 @@ class ChannelModel { 'team', ]; - /// Constructor used for json serialization - ChannelModel({ - this.id, - this.type, - this.cid, - this.config, - this.createdBy, - this.frozen, - this.lastMessageAt, - this.createdAt, - this.updatedAt, - this.deletedAt, - this.memberCount, - this.extraData, - this.team, - }); - /// Shortcut for channel name String get name => extraData?.containsKey('name') == true ? extraData['name'] : cid; - /// Create a new instance from a json - factory ChannelModel.fromJson(Map json) { - return _$ChannelModelFromJson( - Serialization.moveToExtraDataFromRoot(json, topLevelFields)); - } - /// Serialize to json - Map toJson() { - return Serialization.moveFromExtraDataToRoot( - _$ChannelModelToJson(this), - topLevelFields, - ); - } + Map toJson() => Serialization.moveFromExtraDataToRoot( + _$ChannelModelToJson(this), + topLevelFields, + ); /// Creates a copy of [ChannelModel] with specified attributes overridden. ChannelModel copyWith({ @@ -143,8 +139,8 @@ class ChannelModel { team: team ?? this.team, ); - /// Returns a new [ChannelModel] that is a combination of this channelModel and the given - /// [other] channelModel. + /// Returns a new [ChannelModel] that is a combination of this channelModel + /// and the given [other] channelModel. ChannelModel merge(ChannelModel other) { if (other == null) return this; return copyWith( diff --git a/packages/stream_chat/lib/src/models/channel_state.dart b/packages/stream_chat/lib/src/models/channel_state.dart index c2a3d48c5..3a1f3178d 100644 --- a/packages/stream_chat/lib/src/models/channel_state.dart +++ b/packages/stream_chat/lib/src/models/channel_state.dart @@ -1,16 +1,26 @@ import 'package:json_annotation/json_annotation.dart'; - -import '../models/read.dart'; -import '../models/user.dart'; -import 'channel_model.dart'; -import 'member.dart'; -import 'message.dart'; +import 'package:stream_chat/src/models/channel_model.dart'; +import 'package:stream_chat/src/models/member.dart'; +import 'package:stream_chat/src/models/message.dart'; +import 'package:stream_chat/src/models/read.dart'; +import 'package:stream_chat/src/models/user.dart'; part 'channel_state.g.dart'; /// The class that contains the information about a channel @JsonSerializable() class ChannelState { + /// Constructor used for json serialization + ChannelState({ + this.channel, + this.messages = const [], + this.members = const [], + this.pinnedMessages = const [], + this.watcherCount, + this.watchers = const [], + this.read = const [], + }); + /// The channel to which this state belongs final ChannelModel channel; @@ -32,17 +42,6 @@ class ChannelState { /// The list of channel reads final List read; - /// Constructor used for json serialization - ChannelState({ - this.channel, - this.messages = const [], - this.members = const [], - this.pinnedMessages = const [], - this.watcherCount, - this.watchers = const [], - this.read = const [], - }); - /// Create a new instance from a json static ChannelState fromJson(Map json) => _$ChannelStateFromJson(json); diff --git a/packages/stream_chat/lib/src/models/command.dart b/packages/stream_chat/lib/src/models/command.dart index 420f21955..a5ababd2a 100644 --- a/packages/stream_chat/lib/src/models/command.dart +++ b/packages/stream_chat/lib/src/models/command.dart @@ -5,15 +5,6 @@ part 'command.g.dart'; /// The class that contains the information about a command @JsonSerializable() class Command { - /// The name of the command - final String name; - - /// The description explaining the command - final String description; - - /// The arguments of the command - final String args; - /// Constructor used for json serialization Command({ this.name, @@ -25,6 +16,15 @@ class Command { factory Command.fromJson(Map json) => _$CommandFromJson(json); + /// The name of the command + final String name; + + /// The description explaining the command + final String description; + + /// The arguments of the command + final String args; + /// Serialize to json Map toJson() => _$CommandToJson(this); } diff --git a/packages/stream_chat/lib/src/models/device.dart b/packages/stream_chat/lib/src/models/device.dart index 972472221..150e6759c 100644 --- a/packages/stream_chat/lib/src/models/device.dart +++ b/packages/stream_chat/lib/src/models/device.dart @@ -5,12 +5,6 @@ part 'device.g.dart'; /// The class that contains the information about a device @JsonSerializable() class Device { - /// The id of the device - final String id; - - /// The notification push provider - final String pushProvider; - /// Constructor used for json serialization Device({ this.id, @@ -20,6 +14,12 @@ class Device { /// Create a new instance from a json factory Device.fromJson(Map json) => _$DeviceFromJson(json); + /// The id of the device + final String id; + + /// The notification push provider + final String pushProvider; + /// Serialize to json Map toJson() => _$DeviceToJson(this); } diff --git a/packages/stream_chat/lib/src/models/event.dart b/packages/stream_chat/lib/src/models/event.dart index 03995d679..b1140ebc7 100644 --- a/packages/stream_chat/lib/src/models/event.dart +++ b/packages/stream_chat/lib/src/models/event.dart @@ -4,17 +4,40 @@ import 'package:stream_chat/src/models/message.dart'; import 'package:stream_chat/src/models/serialization.dart'; import 'package:stream_chat/stream_chat.dart'; -import '../event_type.dart'; -import 'member.dart'; -import 'own_user.dart'; -import 'reaction.dart'; -import 'user.dart'; - part 'event.g.dart'; /// The class that contains the information about an event @JsonSerializable() class Event { + /// Constructor used for json serialization + Event({ + this.type, + this.cid, + this.connectionId, + this.createdAt, + this.me, + this.user, + this.message, + this.totalUnreadCount, + this.unreadChannels, + this.reaction, + this.online, + this.channel, + this.member, + this.channelId, + this.channelType, + this.parentId, + this.extraData, + }) : isLocal = true; + + /// Create a new instance from a json + factory Event.fromJson(Map json) => + _$EventFromJson(Serialization.moveToExtraDataFromRoot( + json, + topLevelFields, + )) + ..isLocal = false; + /// The type of the event /// [EventType] contains some predefined constant types final String type; @@ -71,27 +94,6 @@ class Event { @JsonKey(includeIfNull: false) final Map extraData; - /// Constructor used for json serialization - Event({ - this.type, - this.cid, - this.connectionId, - this.createdAt, - this.me, - this.user, - this.message, - this.totalUnreadCount, - this.unreadChannels, - this.reaction, - this.online, - this.channel, - this.member, - this.channelId, - this.channelType, - this.parentId, - this.extraData, - }) : isLocal = true; - /// Known top level fields. /// Useful for [Serialization] methods. static final topLevelFields = [ @@ -114,15 +116,6 @@ class Event { 'is_local', ]; - /// Create a new instance from a json - factory Event.fromJson(Map json) { - return _$EventFromJson(Serialization.moveToExtraDataFromRoot( - json, - topLevelFields, - )) - ..isLocal = false; - } - /// Serialize to json Map toJson() => Serialization.moveFromExtraDataToRoot( _$EventToJson(this), @@ -133,16 +126,6 @@ class Event { /// The channel embedded in the event object @JsonSerializable() class EventChannel extends ChannelModel { - /// A paginated list of channel members - final List members; - - /// Known top level fields. - /// Useful for [Serialization] methods. - static final topLevelFields = [ - 'members', - ...ChannelModel.topLevelFields, - ]; - /// Constructor used for json serialization EventChannel({ this.members, @@ -174,12 +157,21 @@ class EventChannel extends ChannelModel { ); /// Create a new instance from a json - factory EventChannel.fromJson(Map json) { - return _$EventChannelFromJson(Serialization.moveToExtraDataFromRoot( - json, - topLevelFields, - )); - } + factory EventChannel.fromJson(Map json) => + _$EventChannelFromJson(Serialization.moveToExtraDataFromRoot( + json, + topLevelFields, + )); + + /// A paginated list of channel members + final List members; + + /// Known top level fields. + /// Useful for [Serialization] methods. + static final topLevelFields = [ + 'members', + ...ChannelModel.topLevelFields, + ]; /// Serialize to json @override diff --git a/packages/stream_chat/lib/src/models/member.dart b/packages/stream_chat/lib/src/models/member.dart index 511b7a7ba..e99d8d345 100644 --- a/packages/stream_chat/lib/src/models/member.dart +++ b/packages/stream_chat/lib/src/models/member.dart @@ -1,12 +1,35 @@ import 'package:json_annotation/json_annotation.dart'; - -import '../models/user.dart'; +import 'package:stream_chat/src/models/user.dart'; part 'member.g.dart'; -/// The class that contains the information about the user membership in a channel +/// The class that contains the information about the user membership +/// in a channel @JsonSerializable() class Member { + /// Constructor used for json serialization + Member({ + this.user, + this.inviteAcceptedAt, + this.inviteRejectedAt, + this.invited, + this.role, + this.userId, + this.isModerator, + this.createdAt, + this.updatedAt, + this.banned, + this.shadowBanned, + }); + + /// Create a new instance from a json + factory Member.fromJson(Map json) { + final member = _$MemberFromJson(json); + return member.copyWith( + userId: member.user?.id, + ); + } + /// The interested user final User user; @@ -40,29 +63,6 @@ class Member { /// The last date of update final DateTime updatedAt; - /// Constructor used for json serialization - Member({ - this.user, - this.inviteAcceptedAt, - this.inviteRejectedAt, - this.invited, - this.role, - this.userId, - this.isModerator, - this.createdAt, - this.updatedAt, - this.banned, - this.shadowBanned, - }); - - /// Create a new instance from a json - factory Member.fromJson(Map json) { - final member = _$MemberFromJson(json); - return member.copyWith( - userId: member.user?.id, - ); - } - /// Creates a copy of [Member] with specified attributes overridden. Member copyWith({ User user, diff --git a/packages/stream_chat/lib/src/models/message.dart b/packages/stream_chat/lib/src/models/message.dart index df1906f3d..a89324a75 100644 --- a/packages/stream_chat/lib/src/models/message.dart +++ b/packages/stream_chat/lib/src/models/message.dart @@ -1,11 +1,10 @@ import 'package:json_annotation/json_annotation.dart'; +import 'package:stream_chat/src/models/attachment.dart'; +import 'package:stream_chat/src/models/reaction.dart'; +import 'package:stream_chat/src/models/serialization.dart'; +import 'package:stream_chat/src/models/user.dart'; import 'package:uuid/uuid.dart'; -import 'attachment.dart'; -import 'reaction.dart'; -import 'serialization.dart'; -import 'user.dart'; - part 'message.g.dart'; class _PinExpires { @@ -29,9 +28,11 @@ enum MessageSendingStatus { failed, /// Message failed to updated + // ignore: constant_identifier_names failed_update, /// Message failed to delete + // ignore: constant_identifier_names failed_delete, /// Message correctly sent @@ -41,7 +42,46 @@ enum MessageSendingStatus { /// The class that contains the information about a message @JsonSerializable() class Message { - /// The message ID. This is either created by Stream or set client side when the message is added. + /// Constructor used for json serialization + Message({ + String id, + this.text, + this.type, + this.attachments, + this.mentionedUsers, + this.silent, + this.shadowed, + this.reactionCounts, + this.reactionScores, + this.latestReactions, + this.ownReactions, + this.parentId, + this.quotedMessage, + this.quotedMessageId, + this.replyCount = 0, + this.threadParticipants, + this.showInChannel, + this.command, + this.createdAt, + this.updatedAt, + this.user, + this.pinned = false, + this.pinnedAt, + DateTime pinExpires, + this.pinnedBy, + this.extraData, + this.deletedAt, + this.status = MessageSendingStatus.sent, + this.skipPush, + }) : id = id ?? Uuid().v4(), + pinExpires = pinExpires?.toUtc(); + + /// Create a new instance from a json + factory Message.fromJson(Map json) => _$MessageFromJson( + Serialization.moveToExtraDataFromRoot(json, topLevelFields)); + + /// The message ID. This is either created by Stream or set client side when + /// the message is added. final String id; /// The text of this message @@ -55,7 +95,8 @@ class Message { @JsonKey(includeIfNull: false, toJson: Serialization.readOnly) final String type; - /// The list of attachments, either provided by the user or generated from a command or as a result of URL scraping. + /// The list of attachments, either provided by the user or generated from a + /// command or as a result of URL scraping. @JsonKey(includeIfNull: false) final List attachments; @@ -103,6 +144,9 @@ class Message { /// If true the message is silent final bool silent; + /// If true the message will not send a push notification + final bool skipPush; + /// If true the message is shadowed @JsonKey(includeIfNull: false, toJson: Serialization.readOnly) final bool shadowed; @@ -186,45 +230,9 @@ class Message { 'pinned_at', 'pin_expires', 'pinned_by', + 'skip_push', ]; - /// Constructor used for json serialization - Message({ - String id, - this.text, - this.type, - this.attachments, - this.mentionedUsers, - this.silent, - this.shadowed, - this.reactionCounts, - this.reactionScores, - this.latestReactions, - this.ownReactions, - this.parentId, - this.quotedMessage, - this.quotedMessageId, - this.replyCount = 0, - this.threadParticipants, - this.showInChannel, - this.command, - this.createdAt, - this.updatedAt, - this.user, - this.pinned = false, - this.pinnedAt, - DateTime pinExpires, - this.pinnedBy, - this.extraData, - this.deletedAt, - this.status = MessageSendingStatus.sent, - }) : id = id ?? Uuid().v4(), - pinExpires = pinExpires?.toUtc(); - - /// Create a new instance from a json - factory Message.fromJson(Map json) => _$MessageFromJson( - Serialization.moveToExtraDataFromRoot(json, topLevelFields)); - /// Serialize to json Map toJson() => Serialization.moveFromExtraDataToRoot( _$MessageToJson(this), topLevelFields); @@ -259,6 +267,7 @@ class Message { User pinnedBy, Map extraData, MessageSendingStatus status, + bool skipPush, }) { assert(() { if (pinExpires is! DateTime && @@ -267,7 +276,7 @@ class Message { throw ArgumentError('`pinExpires` can only be set as DateTime or null'); } return true; - }()); + }(), 'Validate type for pinExpires'); return Message( id: id ?? this.id, text: text ?? this.text, @@ -297,11 +306,12 @@ class Message { pinnedAt: pinnedAt ?? this.pinnedAt, pinnedBy: pinnedBy ?? this.pinnedBy, pinExpires: pinExpires == _pinExpires ? this.pinExpires : pinExpires, + skipPush: skipPush ?? this.skipPush, ); } - /// Returns a new [Message] that is a combination of this message and the given - /// [other] message. + /// Returns a new [Message] that is a combination of this message and the + /// given [other] message. Message merge(Message other) { if (other == null) return this; return copyWith( @@ -344,6 +354,12 @@ class TranslatedMessage extends Message { /// Constructor used for json serialization TranslatedMessage(this.i18n); + /// Create a new instance from a json + factory TranslatedMessage.fromJson(Map json) => + _$TranslatedMessageFromJson( + Serialization.moveToExtraDataFromRoot(json, topLevelFields), + ); + /// A Map of final Map i18n; @@ -354,13 +370,6 @@ class TranslatedMessage extends Message { ...Message.topLevelFields, ]; - /// Create a new instance from a json - factory TranslatedMessage.fromJson(Map json) { - return _$TranslatedMessageFromJson( - Serialization.moveToExtraDataFromRoot(json, topLevelFields), - ); - } - /// Serialize to json @override Map toJson() => Serialization.moveFromExtraDataToRoot( diff --git a/packages/stream_chat/lib/src/models/message.g.dart b/packages/stream_chat/lib/src/models/message.g.dart index f8ac0c3d8..80df15893 100644 --- a/packages/stream_chat/lib/src/models/message.g.dart +++ b/packages/stream_chat/lib/src/models/message.g.dart @@ -93,6 +93,7 @@ Message _$MessageFromJson(Map json) { deletedAt: json['deleted_at'] == null ? null : DateTime.parse(json['deleted_at'] as String), + skipPush: json['skip_push'] as bool, ); } @@ -123,6 +124,7 @@ Map _$MessageToJson(Message instance) { writeNotNull('thread_participants', readonly(instance.threadParticipants)); val['show_in_channel'] = instance.showInChannel; val['silent'] = instance.silent; + val['skip_push'] = instance.skipPush; writeNotNull('shadowed', readonly(instance.shadowed)); writeNotNull('command', readonly(instance.command)); writeNotNull('created_at', readonly(instance.createdAt)); diff --git a/packages/stream_chat/lib/src/models/mute.dart b/packages/stream_chat/lib/src/models/mute.dart index f33a99569..e3d5e1a03 100644 --- a/packages/stream_chat/lib/src/models/mute.dart +++ b/packages/stream_chat/lib/src/models/mute.dart @@ -1,14 +1,19 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:stream_chat/src/models/channel_model.dart'; - -import 'serialization.dart'; -import 'user.dart'; +import 'package:stream_chat/src/models/serialization.dart'; +import 'package:stream_chat/src/models/user.dart'; part 'mute.g.dart'; /// The class that contains the information about a muted user @JsonSerializable() class Mute { + /// Constructor used for json serialization + Mute({this.user, this.channel, this.createdAt, this.updatedAt}); + + /// Create a new instance from a json + factory Mute.fromJson(Map json) => _$MuteFromJson(json); + /// The user that performed the muting action @JsonKey(includeIfNull: false, toJson: Serialization.readOnly) final User user; @@ -25,12 +30,6 @@ class Mute { @JsonKey(includeIfNull: false, toJson: Serialization.readOnly) final DateTime updatedAt; - /// Constructor used for json serialization - Mute({this.user, this.channel, this.createdAt, this.updatedAt}); - - /// Create a new instance from a json - factory Mute.fromJson(Map json) => _$MuteFromJson(json); - /// Serialize to json Map toJson() => _$MuteToJson(this); } diff --git a/packages/stream_chat/lib/src/models/own_user.dart b/packages/stream_chat/lib/src/models/own_user.dart index 3246788c3..18ee2abf6 100644 --- a/packages/stream_chat/lib/src/models/own_user.dart +++ b/packages/stream_chat/lib/src/models/own_user.dart @@ -1,9 +1,8 @@ import 'package:json_annotation/json_annotation.dart'; - -import 'device.dart'; -import 'mute.dart'; -import 'serialization.dart'; -import 'user.dart'; +import 'package:stream_chat/src/models/device.dart'; +import 'package:stream_chat/src/models/mute.dart'; +import 'package:stream_chat/src/models/serialization.dart'; +import 'package:stream_chat/src/models/user.dart'; part 'own_user.g.dart'; @@ -11,6 +10,36 @@ part 'own_user.g.dart'; /// This object can be found in [Event] @JsonSerializable() class OwnUser extends User { + /// Constructor used for json serialization + OwnUser({ + this.devices, + this.mutes, + this.totalUnreadCount, + this.unreadChannels, + this.channelMutes, + String id, + String role, + DateTime createdAt, + DateTime updatedAt, + DateTime lastActive, + bool online, + Map extraData, + bool banned, + }) : super( + id: id, + role: role, + createdAt: createdAt, + updatedAt: updatedAt, + lastActive: lastActive, + online: online, + extraData: extraData, + banned: banned, + ); + + /// Create a new instance from a json + factory OwnUser.fromJson(Map json) => _$OwnUserFromJson( + Serialization.moveToExtraDataFromRoot(json, topLevelFields)); + /// List of user devices @JsonKey(includeIfNull: false, toJson: Serialization.readOnly) final List devices; @@ -42,42 +71,8 @@ class OwnUser extends User { ...User.topLevelFields, ]; - /// Constructor used for json serialization - OwnUser({ - this.devices, - this.mutes, - this.totalUnreadCount, - this.unreadChannels, - this.channelMutes, - String id, - String role, - DateTime createdAt, - DateTime updatedAt, - DateTime lastActive, - bool online, - Map extraData, - bool banned, - }) : super( - id: id, - role: role, - createdAt: createdAt, - updatedAt: updatedAt, - lastActive: lastActive, - online: online, - extraData: extraData, - banned: banned, - ); - - /// Create a new instance from a json - factory OwnUser.fromJson(Map json) { - return _$OwnUserFromJson( - Serialization.moveToExtraDataFromRoot(json, topLevelFields)); - } - /// Serialize to json @override - Map toJson() { - return Serialization.moveFromExtraDataToRoot( - _$OwnUserToJson(this), topLevelFields); - } + Map toJson() => Serialization.moveFromExtraDataToRoot( + _$OwnUserToJson(this), topLevelFields); } diff --git a/packages/stream_chat/lib/src/models/reaction.dart b/packages/stream_chat/lib/src/models/reaction.dart index f09577619..6792bf3f0 100644 --- a/packages/stream_chat/lib/src/models/reaction.dart +++ b/packages/stream_chat/lib/src/models/reaction.dart @@ -1,13 +1,27 @@ import 'package:json_annotation/json_annotation.dart'; - -import 'serialization.dart'; -import 'user.dart'; +import 'package:stream_chat/src/models/serialization.dart'; +import 'package:stream_chat/src/models/user.dart'; part 'reaction.g.dart'; /// The class that defines a reaction @JsonSerializable() class Reaction { + /// Constructor used for json serialization + Reaction({ + this.messageId, + this.createdAt, + this.type, + this.user, + String userId, + this.score, + this.extraData, + }) : userId = userId ?? user?.id; + + /// Create a new instance from a json + factory Reaction.fromJson(Map json) => _$ReactionFromJson( + Serialization.moveToExtraDataFromRoot(json, topLevelFields)); + /// The messageId to which the reaction belongs final String messageId; @@ -43,28 +57,9 @@ class Reaction { 'score', ]; - /// Constructor used for json serialization - Reaction({ - this.messageId, - this.createdAt, - this.type, - this.user, - String userId, - this.score, - this.extraData, - }) : userId = userId ?? user?.id; - - /// Create a new instance from a json - factory Reaction.fromJson(Map json) { - return _$ReactionFromJson( - Serialization.moveToExtraDataFromRoot(json, topLevelFields)); - } - /// Serialize to json - Map toJson() { - return Serialization.moveFromExtraDataToRoot( - _$ReactionToJson(this), topLevelFields); - } + Map toJson() => Serialization.moveFromExtraDataToRoot( + _$ReactionToJson(this), topLevelFields); /// Creates a copy of [Reaction] with specified attributes overridden. Reaction copyWith({ @@ -75,20 +70,19 @@ class Reaction { String userId, int score, Map extraData, - }) { - return Reaction( - messageId: messageId ?? this.messageId, - createdAt: createdAt ?? this.createdAt, - type: type ?? this.type, - user: user ?? this.user, - userId: userId ?? this.userId, - score: score ?? this.score, - extraData: extraData ?? this.extraData, - ); - } + }) => + Reaction( + messageId: messageId ?? this.messageId, + createdAt: createdAt ?? this.createdAt, + type: type ?? this.type, + user: user ?? this.user, + userId: userId ?? this.userId, + score: score ?? this.score, + extraData: extraData ?? this.extraData, + ); - /// Returns a new [Reaction] that is a combination of this reaction and the given - /// [other] reaction. + /// Returns a new [Reaction] that is a combination of this reaction and the + /// given [other] reaction. Reaction merge(Reaction other) { if (other == null) return this; return copyWith( diff --git a/packages/stream_chat/lib/src/models/read.dart b/packages/stream_chat/lib/src/models/read.dart index ae85293d5..2be639d53 100644 --- a/packages/stream_chat/lib/src/models/read.dart +++ b/packages/stream_chat/lib/src/models/read.dart @@ -1,21 +1,11 @@ import 'package:json_annotation/json_annotation.dart'; - -import 'user.dart'; +import 'package:stream_chat/src/models/user.dart'; part 'read.g.dart'; /// The class that defines a read event @JsonSerializable() class Read { - /// Date of the read event - final DateTime lastRead; - - /// User who sent the event - final User user; - - /// Number of unread messages - final int unreadMessages; - /// Constructor used for json serialization Read({ this.lastRead, @@ -26,6 +16,15 @@ class Read { /// Create a new instance from a json factory Read.fromJson(Map json) => _$ReadFromJson(json); + /// Date of the read event + final DateTime lastRead; + + /// User who sent the event + final User user; + + /// Number of unread messages + final int unreadMessages; + /// Serialize to json Map toJson() => _$ReadToJson(this); } diff --git a/packages/stream_chat/lib/src/models/serialization.dart b/packages/stream_chat/lib/src/models/serialization.dart index 239ccb50f..18cdd545d 100644 --- a/packages/stream_chat/lib/src/models/serialization.dart +++ b/packages/stream_chat/lib/src/models/serialization.dart @@ -1,6 +1,7 @@ -import 'user.dart'; +import 'package:stream_chat/src/models/user.dart'; /// Used to avoid to serialize properties to json +// ignore: prefer_void_to_null Null readonly(_) => null; /// Helper class for serialization to and from json @@ -9,9 +10,8 @@ class Serialization { static const Function readOnly = readonly; /// List of users to list of userIds - static List userIds(List users) { - return users?.map((u) => u.id)?.toList(); - } + static List userIds(List users) => + users?.map((u) => u.id)?.toList(); /// Takes unknown json keys and puts them in the `extra_data` key static Map moveToExtraDataFromRoot( @@ -34,7 +34,8 @@ class Serialization { }); } - /// Takes values in `extra_data` key and puts them on the root level of the json map + /// Takes values in `extra_data` key and puts them on the root level of + /// the json map static Map moveFromExtraDataToRoot( Map json, List topLevelFields, diff --git a/packages/stream_chat/lib/src/models/user.dart b/packages/stream_chat/lib/src/models/user.dart index 00ed12002..618c1986e 100644 --- a/packages/stream_chat/lib/src/models/user.dart +++ b/packages/stream_chat/lib/src/models/user.dart @@ -1,12 +1,53 @@ import 'package:json_annotation/json_annotation.dart'; - -import 'serialization.dart'; +import 'package:stream_chat/src/models/serialization.dart'; part 'user.g.dart'; /// The class that defines the user model @JsonSerializable() class User { + /// Constructor used for json serialization + User({ + this.id, + this.role, + this.createdAt, + this.updatedAt, + this.lastActive, + this.online, + this.extraData, + this.banned, + this.teams, + }); + + /// Create a new instance from a json + factory User.fromJson(Map json) => _$UserFromJson( + Serialization.moveToExtraDataFromRoot(json, topLevelFields)); + + /// Use this named constructor to create a new user instance + User.init( + this.id, { + this.online, + this.extraData, + }) : createdAt = null, + updatedAt = null, + lastActive = null, + banned = null, + teams = null, + role = null; + + /// Known top level fields. + /// Useful for [Serialization] methods. + static const topLevelFields = [ + 'id', + 'role', + 'created_at', + 'updated_at', + 'last_active', + 'online', + 'banned', + 'teams', + ]; + /// User id final String id; @@ -42,43 +83,8 @@ class User { @JsonKey(includeIfNull: false) final Map extraData; - /// Known top level fields. - /// Useful for [Serialization] methods. - static const topLevelFields = [ - 'id', - 'role', - 'created_at', - 'updated_at', - 'last_active', - 'online', - 'banned', - 'teams', - ]; - - /// Use this named constructor to create a new user instance - User.init( - this.id, { - this.online, - this.extraData, - }) : createdAt = null, - updatedAt = null, - lastActive = null, - banned = null, - teams = null, - role = null; - - /// Constructor used for json serialization - User({ - this.id, - this.role, - this.createdAt, - this.updatedAt, - this.lastActive, - this.online, - this.extraData, - this.banned, - this.teams, - }); + @override + int get hashCode => id.hashCode; /// Shortcut for user name String get name => @@ -86,23 +92,12 @@ class User { ? extraData['name'] : id; - /// Create a new instance from a json - factory User.fromJson(Map json) { - return _$UserFromJson( - Serialization.moveToExtraDataFromRoot(json, topLevelFields)); - } - - /// Serialize to json - Map toJson() { - return Serialization.moveFromExtraDataToRoot( - _$UserToJson(this), topLevelFields); - } - @override bool operator ==(Object other) => identical(this, other) || other is User && runtimeType == other.runtimeType && id == other.id; - @override - int get hashCode => id.hashCode; + /// Serialize to json + Map toJson() => + Serialization.moveFromExtraDataToRoot(_$UserToJson(this), topLevelFields); } diff --git a/packages/stream_chat/lib/src/platform_detector/platform_detector.dart b/packages/stream_chat/lib/src/platform_detector/platform_detector.dart index 32748256b..58d86db41 100644 --- a/packages/stream_chat/lib/src/platform_detector/platform_detector.dart +++ b/packages/stream_chat/lib/src/platform_detector/platform_detector.dart @@ -1,29 +1,29 @@ -import 'platform_detector_stub.dart' +import 'package:stream_chat/src/platform_detector/platform_detector_stub.dart' if (dart.library.html) 'platform_detector_web.dart' if (dart.library.io) 'platform_detector_io.dart'; /// Possible platforms enum PlatformType { /// - Android, + android, /// - Ios, + ios, /// - Web, + web, /// - MacOS, + macOS, /// - Windows, + windows, /// - Linux, + linux, /// - Fuchsia, + fuchsia, } /// Utility class that provides information on the current platform @@ -31,42 +31,42 @@ class CurrentPlatform { CurrentPlatform._(); /// True if the app is running on android - static bool get isAndroid => type == PlatformType.Android; + static bool get isAndroid => type == PlatformType.android; /// True if the app is running on ios - static bool get isIos => type == PlatformType.Ios; + static bool get isIos => type == PlatformType.ios; /// True if the app is running on web - static bool get isWeb => type == PlatformType.Web; + static bool get isWeb => type == PlatformType.web; /// True if the app is running on macos - static bool get isMacOS => type == PlatformType.MacOS; + static bool get isMacOS => type == PlatformType.macOS; /// True if the app is running on windows - static bool get isWindows => type == PlatformType.Windows; + static bool get isWindows => type == PlatformType.windows; /// True if the app is running on linux - static bool get isLinux => type == PlatformType.Linux; + static bool get isLinux => type == PlatformType.linux; /// True if the app is running on fuchsia - static bool get isFuchsia => type == PlatformType.Fuchsia; + static bool get isFuchsia => type == PlatformType.fuchsia; /// Returns a string version of the platform static String get name { switch (type) { - case PlatformType.Android: + case PlatformType.android: return 'android'; - case PlatformType.Ios: + case PlatformType.ios: return 'ios'; - case PlatformType.Web: + case PlatformType.web: return 'web'; - case PlatformType.MacOS: + case PlatformType.macOS: return 'macos'; - case PlatformType.Windows: + case PlatformType.windows: return 'windows'; - case PlatformType.Linux: + case PlatformType.linux: return 'linux'; - case PlatformType.Fuchsia: + case PlatformType.fuchsia: return 'fuchsia'; default: return ''; diff --git a/packages/stream_chat/lib/src/platform_detector/platform_detector_io.dart b/packages/stream_chat/lib/src/platform_detector/platform_detector_io.dart index df74f5d88..c7b4a0b7f 100644 --- a/packages/stream_chat/lib/src/platform_detector/platform_detector_io.dart +++ b/packages/stream_chat/lib/src/platform_detector/platform_detector_io.dart @@ -1,12 +1,12 @@ import 'dart:io'; -import 'platform_detector.dart'; +import 'package:stream_chat/src/platform_detector/platform_detector.dart'; /// Version running on native systems PlatformType get currentPlatform { - if (Platform.isWindows) return PlatformType.Windows; - if (Platform.isFuchsia) return PlatformType.Fuchsia; - if (Platform.isMacOS) return PlatformType.MacOS; - if (Platform.isLinux) return PlatformType.Linux; - if (Platform.isIOS) return PlatformType.Ios; - return PlatformType.Android; + if (Platform.isWindows) return PlatformType.windows; + if (Platform.isFuchsia) return PlatformType.fuchsia; + if (Platform.isMacOS) return PlatformType.macOS; + if (Platform.isLinux) return PlatformType.linux; + if (Platform.isIOS) return PlatformType.ios; + return PlatformType.android; } diff --git a/packages/stream_chat/lib/src/platform_detector/platform_detector_stub.dart b/packages/stream_chat/lib/src/platform_detector/platform_detector_stub.dart index f9143deb1..b9e13c2e7 100644 --- a/packages/stream_chat/lib/src/platform_detector/platform_detector_stub.dart +++ b/packages/stream_chat/lib/src/platform_detector/platform_detector_stub.dart @@ -1,4 +1,4 @@ -import 'platform_detector.dart'; +import 'package:stream_chat/src/platform_detector/platform_detector.dart'; /// Stub implementation PlatformType get currentPlatform { diff --git a/packages/stream_chat/lib/src/platform_detector/platform_detector_web.dart b/packages/stream_chat/lib/src/platform_detector/platform_detector_web.dart index 4274bf719..ba5d04fc6 100644 --- a/packages/stream_chat/lib/src/platform_detector/platform_detector_web.dart +++ b/packages/stream_chat/lib/src/platform_detector/platform_detector_web.dart @@ -1,4 +1,4 @@ -import 'platform_detector.dart'; +import 'package:stream_chat/src/platform_detector/platform_detector.dart'; /// Version running on web -PlatformType get currentPlatform => PlatformType.Web; +PlatformType get currentPlatform => PlatformType.web; diff --git a/packages/stream_chat/lib/stream_chat.dart b/packages/stream_chat/lib/stream_chat.dart index f0b3e60d4..0e1c9ed2c 100644 --- a/packages/stream_chat/lib/stream_chat.dart +++ b/packages/stream_chat/lib/stream_chat.dart @@ -1,5 +1,6 @@ library stream_chat; +export 'package:async/async.dart'; export 'package:dio/src/dio_error.dart'; export 'package:dio/src/multipart_file.dart'; export 'package:dio/src/options.dart' show ProgressCallback; @@ -12,7 +13,10 @@ export './src/api/requests.dart'; export './src/api/responses.dart'; export './src/attachment_file_uploader.dart' show AttachmentFileUploader; export './src/client.dart'; +export './src/db/chat_persistence_client.dart'; export './src/event_type.dart'; +export './src/extensions/rate_limit.dart'; +export './src/extensions/string_extension.dart'; export './src/models/action.dart'; export './src/models/attachment.dart'; export './src/models/attachment_file.dart'; @@ -29,5 +33,3 @@ export './src/models/own_user.dart'; export './src/models/reaction.dart'; export './src/models/read.dart'; export './src/models/user.dart'; -export './src/extensions/string_extension.dart'; -export './src/db/chat_persistence_client.dart'; diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index 27294084e..207ba25ef 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -2,4 +2,5 @@ import 'package:stream_chat/src/client.dart'; /// Current package version /// Used in [StreamChatClient] to build the `x-stream-client` header -const PACKAGE_VERSION = '1.3.2+1-beta'; +// ignore: constant_identifier_names +const PACKAGE_VERSION = '1.4.0-beta'; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index 927a997e8..410cc5612 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat homepage: https://getstream.io/ description: The official Dart client for Stream Chat, a service for building chat applications. -version: 1.3.2+1-beta +version: 1.4.0-beta repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -9,23 +9,22 @@ environment: sdk: ">=2.7.0 <3.0.0" dependencies: - json_annotation: ^3.0.1 - logging: ^0.11.4 - dio: ^3.0.10 - web_socket_channel: ^1.1.0 - uuid: ^2.2.2 async: ^2.4.2 - rxdart: ^0.25.0 collection: ^1.14.13 - pedantic: ^1.9.2 - meta: ^1.2.4 - mime: ^0.9.7 + dio: ^3.0.10 freezed_annotation: ^0.12.0 http_parser: ^3.1.4 + json_annotation: ^3.0.1 + logging: ^0.11.4 + meta: ^1.2.4 + mime: ^0.9.7 + rxdart: ^0.25.0 + uuid: ^2.2.2 + web_socket_channel: ^1.1.0 dev_dependencies: build_runner: ^1.10.0 + freezed: ^0.12.7 json_serializable: ^3.3.0 - test: ^1.15.7 mockito: ^4.1.1 - freezed: ^0.12.7 + test: ^1.15.7 diff --git a/packages/stream_chat/test/src/client_test.dart b/packages/stream_chat/test/src/client_test.dart index e70724a3a..21b9d09ba 100644 --- a/packages/stream_chat/test/src/client_test.dart +++ b/packages/stream_chat/test/src/client_test.dart @@ -188,7 +188,7 @@ void main() { } }; - final query = 'hello'; + const query = 'hello'; final queryParams = { 'payload': json.encode({ diff --git a/packages/stream_chat/test/src/models/channel_state_test.dart b/packages/stream_chat/test/src/models/channel_state_test.dart index 538f18122..0a14cb76b 100644 --- a/packages/stream_chat/test/src/models/channel_state_test.dart +++ b/packages/stream_chat/test/src/models/channel_state_test.dart @@ -897,6 +897,7 @@ void main() { "show_in_channel": null, "mentioned_users": [], "status": "SENT", + "skip_push": null, "silent": false, "pinned": false, "pinned_at": null, @@ -913,6 +914,7 @@ void main() { "show_in_channel": null, "mentioned_users": [], "status": "SENT", + "skip_push": null, "silent": false, "pinned": false, "pinned_at": null, @@ -922,6 +924,7 @@ void main() { { "id": "dry-meadow-0-53e6299f-9b97-4a9c-a27e-7e2dde49b7e0", "text": "test message", + "skip_push": null, "attachments": [], "parent_id": null, "quoted_message": null, @@ -944,6 +947,7 @@ void main() { "quoted_message_id": null, "show_in_channel": null, "mentioned_users": [], + "skip_push": null, "status": "SENT", "silent": false, "pinned": false, @@ -955,6 +959,7 @@ void main() { "id": "dry-meadow-0-64d7970f-ede8-4b31-9738-1bc1756d2bfe", "text": "test", "attachments": [], + "skip_push": null, "parent_id": null, "quoted_message": null, "quoted_message_id": null, @@ -972,6 +977,7 @@ void main() { "text": "hi", "attachments": [], "parent_id": null, + "skip_push": null, "quoted_message": null, "quoted_message_id": null, "show_in_channel": null, @@ -989,6 +995,7 @@ void main() { "attachments": [], "parent_id": null, "quoted_message": null, + "skip_push": null, "quoted_message_id": null, "show_in_channel": null, "mentioned_users": [], @@ -1011,6 +1018,7 @@ void main() { "status": "SENT", "silent": false, "pinned": false, + "skip_push": null, "pinned_at": null, "pin_expires": null, "pinned_by": null @@ -1028,6 +1036,7 @@ void main() { "silent": false, "pinned": false, "pinned_at": null, + "skip_push": null, "pin_expires": null, "pinned_by": null }, @@ -1039,6 +1048,7 @@ void main() { "quoted_message": null, "quoted_message_id": null, "show_in_channel": null, + "skip_push": null, "mentioned_users": [], "status": "SENT", "silent": false, @@ -1056,6 +1066,7 @@ void main() { "quoted_message_id": null, "show_in_channel": null, "mentioned_users": [], + "skip_push": null, "status": "SENT", "silent": false, "pinned": false, @@ -1074,6 +1085,7 @@ void main() { "mentioned_users": [], "status": "SENT", "silent": false, + "skip_push": null, "pinned": false, "pinned_at": null, "pin_expires": null, @@ -1083,6 +1095,7 @@ void main() { "id": "icy-recipe-7-935c396e-ddf8-4a9a-951c-0a12fa5bf055", "text": "what are you doing?", "attachments": [], + "skip_push": null, "parent_id": null, "quoted_message": null, "quoted_message_id": null, @@ -1100,6 +1113,7 @@ void main() { "text": "👍", "attachments": [], "parent_id": null, + "skip_push": null, "quoted_message": null, "quoted_message_id": null, "show_in_channel": null, @@ -1115,6 +1129,7 @@ void main() { "id": "snowy-credit-3-3e0c1a0d-d22f-42ee-b2a1-f9f49477bf21", "text": "sdasas", "attachments": [], + "skip_push": null, "parent_id": null, "quoted_message": null, "quoted_message_id": null, @@ -1135,6 +1150,7 @@ void main() { "quoted_message": null, "quoted_message_id": null, "show_in_channel": null, + "skip_push": null, "mentioned_users": [], "status": "SENT", "silent": false, @@ -1147,6 +1163,7 @@ void main() { "id": "snowy-credit-3-cfaf0b46-1daa-49c5-947c-b16d6697487d", "text": "nhisagdhsadz", "attachments": [], + "skip_push": null, "parent_id": null, "quoted_message": null, "quoted_message_id": null, @@ -1165,6 +1182,7 @@ void main() { "attachments": [], "parent_id": null, "quoted_message": null, + "skip_push": null, "quoted_message_id": null, "show_in_channel": null, "mentioned_users": [], @@ -1181,6 +1199,7 @@ void main() { "attachments": [], "parent_id": null, "quoted_message": null, + "skip_push": null, "quoted_message_id": null, "show_in_channel": null, "mentioned_users": [], @@ -1188,6 +1207,7 @@ void main() { "silent": false, "pinned": false, "pinned_at": null, + "skip_push": null, "pin_expires": null, "pinned_by": null }, @@ -1204,6 +1224,7 @@ void main() { "silent": false, "pinned": false, "pinned_at": null, + "skip_push": null, "pin_expires": null, "pinned_by": null }, @@ -1220,6 +1241,7 @@ void main() { "silent": false, "pinned": false, "pinned_at": null, + "skip_push": null, "pin_expires": null, "pinned_by": null }, @@ -1236,6 +1258,7 @@ void main() { "silent": false, "pinned": false, "pinned_at": null, + "skip_push": null, "pin_expires": null, "pinned_by": null }, @@ -1252,6 +1275,7 @@ void main() { "silent": false, "pinned": false, "pinned_at": null, + "skip_push": null, "pin_expires": null, "pinned_by": null }, @@ -1268,6 +1292,7 @@ void main() { "silent": false, "pinned": false, "pinned_at": null, + "skip_push": null, "pin_expires": null, "pinned_by": null }, @@ -1284,6 +1309,7 @@ void main() { "silent": false, "pinned": false, "pinned_at": null, + "skip_push": null, "pin_expires": null, "pinned_by": null } diff --git a/packages/stream_chat/test/src/models/message_test.dart b/packages/stream_chat/test/src/models/message_test.dart index fe8fc44ae..3541b2c02 100644 --- a/packages/stream_chat/test/src/models/message_test.dart +++ b/packages/stream_chat/test/src/models/message_test.dart @@ -134,6 +134,7 @@ void main() { "id": "4637f7e4-a06b-42db-ba5a-8d8270dd926f", "text": "https://giphy.com/gifs/the-lion-king-live-action-5zvN79uTGfLMOVfQaA", "silent": false, + "skip_push": null, "attachments": [ { "type": "video", diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 73ac6d4bd..d432f4418 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,17 @@ +## 1.4.0-beta + +- Unfocus `MessageInput` only when sending commands +- Updated default error for `MessageSearchListView` +- Show error messages as system and keep them in the message input +- Remove notification badge logic +- Use shimmer while loading images +- Polished `StreamChatTheme` adding more options and a new `MessageInputTheme` dedicated to `MessageInput` +- Add possibility to specify custom message actions using `MessageWidget.customActions` +- Added `MessageListView.onAttachmentTap` callback +- Fixed message newline issue +- Fixed `MessageListView` scroll keyboard behaviour +- Minor fixes and improveqments + ## 1.3.2-beta - Updated `stream_chat_core` dependency diff --git a/packages/stream_chat_flutter/example/.fvm/flutter_sdk b/packages/stream_chat_flutter/example/.fvm/flutter_sdk new file mode 120000 index 000000000..cdf17889e --- /dev/null +++ b/packages/stream_chat_flutter/example/.fvm/flutter_sdk @@ -0,0 +1 @@ +/Users/salvatoregiordano/fvm/versions/beta \ No newline at end of file diff --git a/packages/stream_chat_flutter/example/.fvm/fvm_config.json b/packages/stream_chat_flutter/example/.fvm/fvm_config.json new file mode 100644 index 000000000..6504dcd01 --- /dev/null +++ b/packages/stream_chat_flutter/example/.fvm/fvm_config.json @@ -0,0 +1,3 @@ +{ + "flutterSdkVersion": "beta" +} \ No newline at end of file diff --git a/packages/stream_chat_flutter/example/android/app/build.gradle b/packages/stream_chat_flutter/example/android/app/build.gradle index 5a4d759a4..9bb36eac5 100644 --- a/packages/stream_chat_flutter/example/android/app/build.gradle +++ b/packages/stream_chat_flutter/example/android/app/build.gradle @@ -34,6 +34,7 @@ android { lintOptions { disable 'InvalidPackage' + checkReleaseBuilds false } defaultConfig { diff --git a/packages/stream_chat_flutter/example/android/app/src/main/AndroidManifest.xml b/packages/stream_chat_flutter/example/android/app/src/main/AndroidManifest.xml index 3197993b5..42c5fa1ea 100644 --- a/packages/stream_chat_flutter/example/android/app/src/main/AndroidManifest.xml +++ b/packages/stream_chat_flutter/example/android/app/src/main/AndroidManifest.xml @@ -7,7 +7,7 @@ FlutterApplication and put your custom class here. --> + + + + + + + diff --git a/packages/stream_chat_flutter/example/android/app/src/main/res/values-night/styles.xml b/packages/stream_chat_flutter/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000..449a9f930 --- /dev/null +++ b/packages/stream_chat_flutter/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/packages/stream_chat_flutter/example/android/build.gradle b/packages/stream_chat_flutter/example/android/build.gradle index dc5cdbc9d..9afae7f84 100644 --- a/packages/stream_chat_flutter/example/android/build.gradle +++ b/packages/stream_chat_flutter/example/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.0.1' + classpath 'com.android.tools.build:gradle:3.6.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/stream_chat_flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/stream_chat_flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16e..919434a62 100644 --- a/packages/stream_chat_flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/stream_chat_flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/stream_chat_flutter/example/lib/tutorial-part-6.dart b/packages/stream_chat_flutter/example/lib/tutorial-part-6.dart index 59dde1ee0..110cc1dc6 100644 --- a/packages/stream_chat_flutter/example/lib/tutorial-part-6.dart +++ b/packages/stream_chat_flutter/example/lib/tutorial-part-6.dart @@ -44,7 +44,12 @@ class MyApp extends StatelessWidget { final defaultTheme = StreamChatThemeData.fromTheme(themeData); final colorTheme = defaultTheme.colorTheme; final customTheme = defaultTheme.merge(StreamChatThemeData( - ownMessageTheme: MessageTheme( + channelPreviewTheme: ChannelPreviewTheme( + avatarTheme: AvatarTheme( + borderRadius: BorderRadius.circular(8), + ), + ), + otherMessageTheme: MessageTheme( messageBackgroundColor: colorTheme.black, messageText: TextStyle( color: colorTheme.white, diff --git a/packages/stream_chat_flutter/example/pubspec.yaml b/packages/stream_chat_flutter/example/pubspec.yaml index 4d32fb58c..0c7ac24d2 100644 --- a/packages/stream_chat_flutter/example/pubspec.yaml +++ b/packages/stream_chat_flutter/example/pubspec.yaml @@ -25,7 +25,11 @@ dependencies: sdk: flutter stream_chat_flutter: path: ../ - stream_chat_persistence: ^1.3.0-beta + stream_chat_persistence: + git: + url: https://github.com/GetStream/stream-chat-flutter.git + ref: develop + path: packages/stream_chat_persistence # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/packages/stream_chat_flutter/example/web/favicon.png b/packages/stream_chat_flutter/example/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/example/web/icons/Icon-192.png b/packages/stream_chat_flutter/example/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/example/web/icons/Icon-512.png b/packages/stream_chat_flutter/example/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 zcmd5=2T+s!lYZ%-(h(2@5fr2dC?F^$C=i-}R6$UX8af(!je;W5yC_|HmujSgN*6?W z3knF*TL1$|?oD*=zPbBVex*RUIKsL<(&Rj9%^UD2IK3W?2j>D?eWQgvS-HLymHo9%~|N2Q{~j za?*X-{b9JRowv_*Mh|;*-kPFn>PI;r<#kFaxFqbn?aq|PduQg=2Q;~Qc}#z)_T%x9 zE|0!a70`58wjREmAH38H1)#gof)U3g9FZ^ zF7&-0^Hy{4XHWLoC*hOG(dg~2g6&?-wqcpf{ z&3=o8vw7lMi22jCG9RQbv8H}`+}9^zSk`nlR8?Z&G2dlDy$4#+WOlg;VHqzuE=fM@ z?OI6HEJH4&tA?FVG}9>jAnq_^tlw8NbjNhfqk2rQr?h(F&WiKy03Sn=-;ZJRh~JrD zbt)zLbnabttEZ>zUiu`N*u4sfQaLE8-WDn@tHp50uD(^r-}UsUUu)`!Rl1PozAc!a z?uj|2QDQ%oV-jxUJmJycySBINSKdX{kDYRS=+`HgR2GO19fg&lZKyBFbbXhQV~v~L za^U944F1_GtuFXtvDdDNDvp<`fqy);>Vw=ncy!NB85Tw{&sT5&Ox%-p%8fTS;OzlRBwErvO+ROe?{%q-Zge=%Up|D4L#>4K@Ke=x%?*^_^P*KD zgXueMiS63!sEw@fNLB-i^F|@Oib+S4bcy{eu&e}Xvb^(mA!=U=Xr3||IpV~3K zQWzEsUeX_qBe6fky#M zzOJm5b+l;~>=sdp%i}}0h zO?B?i*W;Ndn02Y0GUUPxERG`3Bjtj!NroLoYtyVdLtl?SE*CYpf4|_${ku2s`*_)k zN=a}V8_2R5QANlxsq!1BkT6$4>9=-Ix4As@FSS;1q^#TXPrBsw>hJ}$jZ{kUHoP+H zvoYiR39gX}2OHIBYCa~6ERRPJ#V}RIIZakUmuIoLF*{sO8rAUEB9|+A#C|@kw5>u0 zBd=F!4I)Be8ycH*)X1-VPiZ+Ts8_GB;YW&ZFFUo|Sw|x~ZajLsp+_3gv((Q#N>?Jz zFBf`~p_#^${zhPIIJY~yo!7$-xi2LK%3&RkFg}Ax)3+dFCjGgKv^1;lUzQlPo^E{K zmCnrwJ)NuSaJEmueEPO@(_6h3f5mFffhkU9r8A8(JC5eOkux{gPmx_$Uv&|hyj)gN zd>JP8l2U&81@1Hc>#*su2xd{)T`Yw< zN$dSLUN}dfx)Fu`NcY}TuZ)SdviT{JHaiYgP4~@`x{&h*Hd>c3K_To9BnQi@;tuoL z%PYQo&{|IsM)_>BrF1oB~+`2_uZQ48z9!)mtUR zdfKE+b*w8cPu;F6RYJiYyV;PRBbThqHBEu_(U{(gGtjM}Zi$pL8Whx}<JwE3RM0F8x7%!!s)UJVq|TVd#hf1zVLya$;mYp(^oZQ2>=ZXU1c$}f zm|7kfk>=4KoQoQ!2&SOW5|JP1)%#55C$M(u4%SP~tHa&M+=;YsW=v(Old9L3(j)`u z2?#fK&1vtS?G6aOt@E`gZ9*qCmyvc>Ma@Q8^I4y~f3gs7*d=ATlP>1S zyF=k&6p2;7dn^8?+!wZO5r~B+;@KXFEn^&C=6ma1J7Au6y29iMIxd7#iW%=iUzq&C=$aPLa^Q zncia$@TIy6UT@69=nbty5epP>*fVW@5qbUcb2~Gg75dNd{COFLdiz3}kODn^U*=@E z0*$7u7Rl2u)=%fk4m8EK1ctR!6%Ve`e!O20L$0LkM#f+)n9h^dn{n`T*^~d+l*Qlx z$;JC0P9+en2Wlxjwq#z^a6pdnD6fJM!GV7_%8%c)kc5LZs_G^qvw)&J#6WSp< zmsd~1-(GrgjC56Pdf6#!dt^y8Rg}!#UXf)W%~PeU+kU`FeSZHk)%sFv++#Dujk-~m zFHvVJC}UBn2jN& zs!@nZ?e(iyZPNo`p1i#~wsv9l@#Z|ag3JR>0#u1iW9M1RK1iF6-RbJ4KYg?B`dET9 zyR~DjZ>%_vWYm*Z9_+^~hJ_|SNTzBKx=U0l9 z9x(J96b{`R)UVQ$I`wTJ@$_}`)_DyUNOso6=WOmQKI1e`oyYy1C&%AQU<0-`(ow)1 zT}gYdwWdm4wW6|K)LcfMe&psE0XGhMy&xS`@vLi|1#Za{D6l@#D!?nW87wcscUZgELT{Cz**^;Zb~7 z(~WFRO`~!WvyZAW-8v!6n&j*PLm9NlN}BuUN}@E^TX*4Or#dMMF?V9KBeLSiLO4?B zcE3WNIa-H{ThrlCoN=XjOGk1dT=xwwrmt<1a)mrRzg{35`@C!T?&_;Q4Ce=5=>z^*zE_c(0*vWo2_#TD<2)pLXV$FlwP}Ik74IdDQU@yhkCr5h zn5aa>B7PWy5NQ!vf7@p_qtC*{dZ8zLS;JetPkHi>IvPjtJ#ThGQD|Lq#@vE2xdl%`x4A8xOln}BiQ92Po zW;0%A?I5CQ_O`@Ad=`2BLPPbBuPUp@Hb%a_OOI}y{Rwa<#h z5^6M}s7VzE)2&I*33pA>e71d78QpF>sNK;?lj^Kl#wU7G++`N_oL4QPd-iPqBhhs| z(uVM}$ItF-onXuuXO}o$t)emBO3Hjfyil@*+GF;9j?`&67GBM;TGkLHi>@)rkS4Nj zAEk;u)`jc4C$qN6WV2dVd#q}2X6nKt&X*}I@jP%Srs%%DS92lpDY^K*Sx4`l;aql$ zt*-V{U&$DM>pdO?%jt$t=vg5|p+Rw?SPaLW zB6nvZ69$ne4Z(s$3=Rf&RX8L9PWMV*S0@R zuIk&ba#s6sxVZ51^4Kon46X^9`?DC9mEhWB3f+o4#2EXFqy0(UTc>GU| zGCJmI|Dn-dX#7|_6(fT)>&YQ0H&&JX3cTvAq(a@ydM4>5Njnuere{J8p;3?1az60* z$1E7Yyxt^ytULeokgDnRVKQw9vzHg1>X@@jM$n$HBlveIrKP5-GJq%iWH#odVwV6cF^kKX(@#%%uQVb>#T6L^mC@)%SMd4DF? zVky!~ge27>cpUP1Vi}Z32lbLV+CQy+T5Wdmva6Fg^lKb!zrg|HPU=5Qu}k;4GVH+x z%;&pN1LOce0w@9i1Mo-Y|7|z}fbch@BPp2{&R-5{GLoeu8@limQmFF zaJRR|^;kW_nw~0V^ zfTnR!Ni*;-%oSHG1yItARs~uxra|O?YJxBzLjpeE-=~TO3Dn`JL5Gz;F~O1u3|FE- zvK2Vve`ylc`a}G`gpHg58Cqc9fMoy1L}7x7T>%~b&irrNMo?np3`q;d3d;zTK>nrK zOjPS{@&74-fA7j)8uT9~*g23uGnxwIVj9HorzUX#s0pcp2?GH6i}~+kv9fWChtPa_ z@T3m+$0pbjdQw7jcnHn;Pi85hk_u2-1^}c)LNvjdam8K-XJ+KgKQ%!?2n_!#{$H|| zLO=%;hRo6EDmnOBKCL9Cg~ETU##@u^W_5joZ%Et%X_n##%JDOcsO=0VL|Lkk!VdRJ z^|~2pB@PUspT?NOeO?=0Vb+fAGc!j%Ufn-cB`s2A~W{Zj{`wqWq_-w0wr@6VrM zbzni@8c>WS!7c&|ZR$cQ;`niRw{4kG#e z70e!uX8VmP23SuJ*)#(&R=;SxGAvq|&>geL&!5Z7@0Z(No*W561n#u$Uc`f9pD70# z=sKOSK|bF~#khTTn)B28h^a1{;>EaRnHj~>i=Fnr3+Fa4 z`^+O5_itS#7kPd20rq66_wH`%?HNzWk@XFK0n;Z@Cx{kx==2L22zWH$Yg?7 zvDj|u{{+NR3JvUH({;b*$b(U5U z7(lF!1bz2%06+|-v(D?2KgwNw7( zJB#Tz+ZRi&U$i?f34m7>uTzO#+E5cbaiQ&L}UxyOQq~afbNB4EI{E04ZWg53w0A{O%qo=lF8d zf~ktGvIgf-a~zQoWf>loF7pOodrd0a2|BzwwPDV}ShauTK8*fmF6NRbO>Iw9zZU}u zw8Ya}?seBnEGQDmH#XpUUkj}N49tP<2jYwTFp!P+&Fd(%Z#yo80|5@zN(D{_pNow*&4%ql zW~&yp@scb-+Qj-EmErY+Tu=dUmf@*BoXY2&oKT8U?8?s1d}4a`Aq>7SV800m$FE~? zjmz(LY+Xx9sDX$;vU`xgw*jLw7dWOnWWCO8o|;}f>cu0Q&`0I{YudMn;P;L3R-uz# zfns_mZED_IakFBPP2r_S8XM$X)@O-xVKi4`7373Jkd5{2$M#%cRhWer3M(vr{S6>h zj{givZJ3(`yFL@``(afn&~iNx@B1|-qfYiZu?-_&Z8+R~v`d6R-}EX9IVXWO-!hL5 z*k6T#^2zAXdardU3Ao~I)4DGdAv2bx{4nOK`20rJo>rmk3S2ZDu}))8Z1m}CKigf0 z3L`3Y`{huj`xj9@`$xTZzZc3je?n^yG<8sw$`Y%}9mUsjUR%T!?k^(q)6FH6Af^b6 zlPg~IEwg0y;`t9y;#D+uz!oE4VP&Je!<#q*F?m5L5?J3i@!0J6q#eu z!RRU`-)HeqGi_UJZ(n~|PSNsv+Wgl{P-TvaUQ9j?ZCtvb^37U$sFpBrkT{7Jpd?HpIvj2!}RIq zH{9~+gErN2+}J`>Jvng2hwM`=PLNkc7pkjblKW|+Fk9rc)G1R>Ww>RC=r-|!m-u7( zc(a$9NG}w#PjWNMS~)o=i~WA&4L(YIW25@AL9+H9!?3Y}sv#MOdY{bb9j>p`{?O(P zIvb`n?_(gP2w3P#&91JX*md+bBEr%xUHMVqfB;(f?OPtMnAZ#rm5q5mh;a2f_si2_ z3oXWB?{NF(JtkAn6F(O{z@b76OIqMC$&oJ_&S|YbFJ*)3qVX_uNf5b8(!vGX19hsG z(OP>RmZp29KH9Ge2kKjKigUmOe^K_!UXP`von)PR8Qz$%=EmOB9xS(ZxE_tnyzo}7 z=6~$~9k0M~v}`w={AeqF?_)9q{m8K#6M{a&(;u;O41j)I$^T?lx5(zlebpY@NT&#N zR+1bB)-1-xj}R8uwqwf=iP1GbxBjneCC%UrSdSxK1vM^i9;bUkS#iRZw2H>rS<2<$ zNT3|sDH>{tXb=zq7XZi*K?#Zsa1h1{h5!Tq_YbKFm_*=A5-<~j63he;4`77!|LBlo zR^~tR3yxcU=gDFbshyF6>o0bdp$qmHS7D}m3;^QZq9kBBU|9$N-~oU?G5;jyFR7>z hN`IR97YZXIo@y!QgFWddJ3|0`sjFx!m))><{BI=FK%f8s literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/example/web/index.html b/packages/stream_chat_flutter/example/web/index.html new file mode 100644 index 000000000..fb0535656 --- /dev/null +++ b/packages/stream_chat_flutter/example/web/index.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + example + + + + + + + + diff --git a/packages/stream_chat_flutter/example/web/manifest.json b/packages/stream_chat_flutter/example/web/manifest.json new file mode 100644 index 000000000..8c012917d --- /dev/null +++ b/packages/stream_chat_flutter/example/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/packages/stream_chat_flutter/example/web/sql-wasm.js b/packages/stream_chat_flutter/example/web/sql-wasm.js new file mode 100644 index 000000000..f04a231d6 --- /dev/null +++ b/packages/stream_chat_flutter/example/web/sql-wasm.js @@ -0,0 +1,203 @@ + +// We are modularizing this manually because the current modularize setting in Emscripten has some issues: +// https://github.com/kripken/emscripten/issues/5820 +// In addition, When you use emcc's modularization, it still expects to export a global object called `Module`, +// which is able to be used/called before the WASM is loaded. +// The modularization below exports a promise that loads and resolves to the actual sql.js module. +// That way, this module can't be used before the WASM is finished loading. + +// We are going to define a function that a user will call to start loading initializing our Sql.js library +// However, that function might be called multiple times, and on subsequent calls, we don't actually want it to instantiate a new instance of the Module +// Instead, we want to return the previously loaded module + +// TODO: Make this not declare a global if used in the browser +var initSqlJsPromise = undefined; + +var initSqlJs = function (moduleConfig) { + + if (initSqlJsPromise){ + return initSqlJsPromise; + } + // If we're here, we've never called this function before + initSqlJsPromise = new Promise(function (resolveModule, reject) { + + // We are modularizing this manually because the current modularize setting in Emscripten has some issues: + // https://github.com/kripken/emscripten/issues/5820 + + // The way to affect the loading of emcc compiled modules is to create a variable called `Module` and add + // properties to it, like `preRun`, `postRun`, etc + // We are using that to get notified when the WASM has finished loading. + // Only then will we return our promise + + // If they passed in a moduleConfig object, use that + // Otherwise, initialize Module to the empty object + var Module = typeof moduleConfig !== 'undefined' ? moduleConfig : {}; + + // EMCC only allows for a single onAbort function (not an array of functions) + // So if the user defined their own onAbort function, we remember it and call it + var originalOnAbortFunction = Module['onAbort']; + Module['onAbort'] = function (errorThatCausedAbort) { + reject(new Error(errorThatCausedAbort)); + if (originalOnAbortFunction){ + originalOnAbortFunction(errorThatCausedAbort); + } + }; + + Module['postRun'] = Module['postRun'] || []; + Module['postRun'].push(function () { + // When Emscripted calls postRun, this promise resolves with the built Module + resolveModule(Module); + }); + + // There is a section of code in the emcc-generated code below that looks like this: + // (Note that this is lowercase `module`) + // if (typeof module !== 'undefined') { + // module['exports'] = Module; + // } + // When that runs, it's going to overwrite our own modularization export efforts in shell-post.js! + // The only way to tell emcc not to emit it is to pass the MODULARIZE=1 or MODULARIZE_INSTANCE=1 flags, + // but that carries with it additional unnecessary baggage/bugs we don't want either. + // So, we have three options: + // 1) We undefine `module` + // 2) We remember what `module['exports']` was at the beginning of this function and we restore it later + // 3) We write a script to remove those lines of code as part of the Make process. + // + // Since those are the only lines of code that care about module, we will undefine it. It's the most straightforward + // of the options, and has the side effect of reducing emcc's efforts to modify the module if its output were to change in the future. + // That's a nice side effect since we're handling the modularization efforts ourselves + module = undefined; + + // The emcc-generated code and shell-post.js code goes below, + // meaning that all of it runs inside of this promise. If anything throws an exception, our promise will abort + +var e;e||(e=typeof Module !== 'undefined' ? Module : {});null; +e.onRuntimeInitialized=function(){function a(h,l){this.Ra=h;this.db=l;this.Qa=1;this.lb=[]}function b(h,l){this.db=l;l=aa(h)+1;this.eb=ba(l);if(null===this.eb)throw Error("Unable to allocate memory for the SQL string");k(h,m,this.eb,l);this.jb=this.eb;this.$a=this.pb=null}function c(h){this.filename="dbfile_"+(4294967295*Math.random()>>>0);if(null!=h){var l=this.filename,p=l?r("//"+l):"/";l=ca(!0,!0);p=da(p,(void 0!==l?l:438)&4095|32768,0);if(h){if("string"===typeof h){for(var q=Array(h.length),B= +0,ha=h.length;Bd;++d)g.parameters.push(f["viii"[d]]); +d=new WebAssembly.Function(g,a)}else{f=[1,0,1,96];g={i:127,j:126,f:125,d:124};f.push(3);for(d=0;3>d;++d)f.push(g["iii"[d]]);f.push(0);f[1]=f.length-2;d=new Uint8Array([0,97,115,109,1,0,0,0].concat(f,[2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0]));d=new WebAssembly.Module(d);d=(new WebAssembly.Instance(d,{e:{f:a}})).exports.f}b.set(c,d)}Ia.set(a,c);a=c}return a}function ra(a){ua(a)}var Ka;e.wasmBinary&&(Ka=e.wasmBinary);var noExitRuntime;e.noExitRuntime&&(noExitRuntime=e.noExitRuntime); +"object"!==typeof WebAssembly&&K("no native wasm support detected"); +function pa(a){var b="i32";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":z[a>>0]=0;break;case "i8":z[a>>0]=0;break;case "i16":La[a>>1]=0;break;case "i32":L[a>>2]=0;break;case "i64":M=[0,(N=0,1<=+Math.abs(N)?0>>0:~~+Math.ceil((N-+(~~N>>>0))/4294967296)>>>0:0)];L[a>>2]=M[0];L[a+4>>2]=M[1];break;case "float":Ma[a>>2]=0;break;case "double":Na[a>>3]=0;break;default:K("invalid type for setValue: "+b)}} +function x(a,b){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return z[a>>0];case "i8":return z[a>>0];case "i16":return La[a>>1];case "i32":return L[a>>2];case "i64":return L[a>>2];case "float":return Ma[a>>2];case "double":return Na[a>>3];default:K("invalid type for getValue: "+b)}return null}var Oa,Ja,Pa=!1;function assert(a,b){a||K("Assertion failed: "+b)}function Qa(a){var b=e["_"+a];assert(b,"Cannot call unknown function "+a+", make sure it is exported");return b} +function Ra(a,b,c,d){var f={string:function(v){var C=0;if(null!==v&&void 0!==v&&0!==v){var H=(v.length<<2)+1;C=y(H);k(v,m,C,H)}return C},array:function(v){var C=y(v.length);z.set(v,C);return C}},g=Qa(a),n=[];a=0;if(d)for(var t=0;t=d);)++c;if(16f?d+=String.fromCharCode(f):(f-=65536,d+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else d+=String.fromCharCode(f)}return d}function A(a,b){return a?Va(m,a,b):""} +function k(a,b,c,d){if(!(0=n){var t=a.charCodeAt(++g);n=65536+((n&1023)<<10)|t&1023}if(127>=n){if(c>=d)break;b[c++]=n}else{if(2047>=n){if(c+1>=d)break;b[c++]=192|n>>6}else{if(65535>=n){if(c+2>=d)break;b[c++]=224|n>>12}else{if(c+3>=d)break;b[c++]=240|n>>18;b[c++]=128|n>>12&63}b[c++]=128|n>>6&63}b[c++]=128|n&63}}b[c]=0;return c-f} +function aa(a){for(var b=0,c=0;c=d&&(d=65536+((d&1023)<<10)|a.charCodeAt(++c)&1023);127>=d?++b:b=2047>=d?b+2:65535>=d?b+3:b+4}return b}function Wa(a){var b=aa(a)+1,c=ba(b);c&&k(a,z,c,b);return c}var Xa,z,m,La,L,Ma,Na; +function Ya(a){Xa=a;e.HEAP8=z=new Int8Array(a);e.HEAP16=La=new Int16Array(a);e.HEAP32=L=new Int32Array(a);e.HEAPU8=m=new Uint8Array(a);e.HEAPU16=new Uint16Array(a);e.HEAPU32=new Uint32Array(a);e.HEAPF32=Ma=new Float32Array(a);e.HEAPF64=Na=new Float64Array(a)}var Za=e.INITIAL_MEMORY||16777216;e.wasmMemory?Oa=e.wasmMemory:Oa=new WebAssembly.Memory({initial:Za/65536,maximum:32768});Oa&&(Xa=Oa.buffer);Za=Xa.byteLength;Ya(Xa);var $a=[],ab=[],bb=[],cb=[]; +function db(){var a=e.preRun.shift();$a.unshift(a)}var eb=0,fb=null,gb=null;e.preloadedImages={};e.preloadedAudios={};function K(a){if(e.onAbort)e.onAbort(a);J(a);Pa=!0;throw new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");}function hb(a){var b=ib;return String.prototype.startsWith?b.startsWith(a):0===b.indexOf(a)}function jb(){return hb("data:application/octet-stream;base64,")}var ib="sql-wasm.wasm"; +if(!jb()){var kb=ib;ib=e.locateFile?e.locateFile(kb,I):I+kb}function lb(){try{if(Ka)return new Uint8Array(Ka);if(Ca)return Ca(ib);throw"both async and sync fetching of the wasm failed";}catch(a){K(a)}}function mb(){return Ka||!ya&&!G||"function"!==typeof fetch||hb("file://")?Promise.resolve().then(lb):fetch(ib,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+ib+"'";return a.arrayBuffer()}).catch(function(){return lb()})}var N,M; +function nb(a){for(;0>2]=60*(new Date).getTimezoneOffset();var b=(new Date).getFullYear(),c=new Date(b,0,1);b=new Date(b,6,1);L[vb()>>2]=Number(c.getTimezoneOffset()!=b.getTimezoneOffset());var d=a(c),f=a(b);d=Wa(d);f=Wa(f);b.getTimezoneOffset()>2]=d,L[xb()+4>>2]=f):(L[xb()>>2]=f,L[xb()+4>>2]=d)}}var tb; +function yb(a,b){for(var c=0,d=a.length-1;0<=d;d--){var f=a[d];"."===f?a.splice(d,1):".."===f?(a.splice(d,1),c++):c&&(a.splice(d,1),c--)}if(b)for(;c;c--)a.unshift("..");return a}function r(a){var b="/"===a.charAt(0),c="/"===a.substr(-1);(a=yb(a.split("/").filter(function(d){return!!d}),!b).join("/"))||b||(a=".");a&&c&&(a+="/");return(b?"/":"")+a} +function zb(a){var b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1);a=b[0];b=b[1];if(!a&&!b)return".";b&&(b=b.substr(0,b.length-1));return a+b}function Ab(a){if("/"===a)return"/";a=r(a);a=a.replace(/\/$/,"");var b=a.lastIndexOf("/");return-1===b?a:a.substr(b+1)}function Bb(a){L[Cb()>>2]=a} +function Db(){if("object"===typeof crypto&&"function"===typeof crypto.getRandomValues){var a=new Uint8Array(1);return function(){crypto.getRandomValues(a);return a[0]}}if(za)try{var b=require("crypto");return function(){return b.randomBytes(1)[0]}}catch(c){}return function(){K("randomDevice")}} +function Eb(){for(var a="",b=!1,c=arguments.length-1;-1<=c&&!b;c--){b=0<=c?arguments[c]:"/";if("string"!==typeof b)throw new TypeError("Arguments to path.resolve must be strings");if(!b)return"";a=b+"/"+a;b="/"===b.charAt(0)}a=yb(a.split("/").filter(function(d){return!!d}),!b).join("/");return(b?"/":"")+a||"."}var Fb=[];function Gb(a,b){Fb[a]={input:[],output:[],cb:b};Hb(a,Ib)} +var Ib={open:function(a){var b=Fb[a.node.rdev];if(!b)throw new O(43);a.tty=b;a.seekable=!1},close:function(a){a.tty.cb.flush(a.tty)},flush:function(a){a.tty.cb.flush(a.tty)},read:function(a,b,c,d){if(!a.tty||!a.tty.cb.xb)throw new O(60);for(var f=0,g=0;g=b||(b=Math.max(b,c*(1048576>c?2:1.125)>>>0),0!=c&&(b=Math.max(b,256)),c=a.Ma,a.Ma=new Uint8Array(b),0b)a.Ma.length=b;else for(;a.Ma.length=a.node.Sa)return 0;a=Math.min(a.node.Sa-f,d);if(8b)throw new O(28);return b},sb:function(a,b,c){P.vb(a.node,b+c);a.node.Sa=Math.max(a.node.Sa,b+c)},hb:function(a,b,c,d,f,g){assert(0===b);if(32768!==(a.node.mode&61440))throw new O(43);a=a.node.Ma; +if(g&2||a.buffer!==Xa){if(0>>0)%T.length}function Wb(a){var b=Vb(a.parent.id,a.name);if(T[b]===a)T[b]=a.bb;else for(b=T[b];b;){if(b.bb===a){b.bb=a.bb;break}b=b.bb}} +function Ob(a,b){var c;if(c=(c=Xb(a,"x"))?c:a.Na.lookup?0:2)throw new O(c,a);for(c=T[Vb(a.id,b)];c;c=c.bb){var d=c.name;if(c.parent.id===a.id&&d===b)return c}return a.Na.lookup(a,b)}function Mb(a,b,c,d){a=new Yb(a,b,c,d);b=Vb(a.parent.id,a.name);a.bb=T[b];return T[b]=a}function Q(a){return 16384===(a&61440)}var Zb={r:0,rs:1052672,"r+":2,w:577,wx:705,xw:705,"w+":578,"wx+":706,"xw+":706,a:1089,ax:1217,xa:1217,"a+":1090,"ax+":1218,"xa+":1218}; +function $b(a){var b=["r","w","rw"][a&3];a&512&&(b+="w");return b}function Xb(a,b){if(Sb)return 0;if(-1===b.indexOf("r")||a.mode&292){if(-1!==b.indexOf("w")&&!(a.mode&146)||-1!==b.indexOf("x")&&!(a.mode&73))return 2}else return 2;return 0}function ac(a,b){try{return Ob(a,b),20}catch(c){}return Xb(a,"wx")}function bc(a,b,c){try{var d=Ob(a,b)}catch(f){return f.Pa}if(a=Xb(a,"wx"))return a;if(c){if(!Q(d.mode))return 54;if(d===d.parent||"/"===Ub(d))return 10}else if(Q(d.mode))return 31;return 0} +function cc(a){var b=4096;for(a=a||0;a<=b;a++)if(!S[a])return a;throw new O(33);}function dc(a,b){ec||(ec=function(){},ec.prototype={});var c=new ec,d;for(d in a)c[d]=a[d];a=c;b=cc(b);a.fd=b;return S[b]=a}var Lb={open:function(a){a.Oa=Qb[a.node.rdev].Oa;a.Oa.open&&a.Oa.open(a)},Za:function(){throw new O(70);}};function Hb(a,b){Qb[a]={Oa:b}} +function fc(a,b){var c="/"===b,d=!b;if(c&&Pb)throw new O(10);if(!c&&!d){var f=V(b,{wb:!1});b=f.path;f=f.node;if(f.ab)throw new O(10);if(!Q(f.mode))throw new O(54);}b={type:a,Ub:{},yb:b,Mb:[]};a=a.Wa(b);a.Wa=b;b.root=a;c?Pb=a:f&&(f.ab=b,f.Wa&&f.Wa.Mb.push(b))}function da(a,b,c){var d=V(a,{parent:!0}).node;a=Ab(a);if(!a||"."===a||".."===a)throw new O(28);var f=ac(d,a);if(f)throw new O(f);if(!d.Na.gb)throw new O(63);return d.Na.gb(d,a,b,c)}function W(a,b){da(a,(void 0!==b?b:511)&1023|16384,0)} +function hc(a,b,c){"undefined"===typeof c&&(c=b,b=438);da(a,b|8192,c)}function ic(a,b){if(!Eb(a))throw new O(44);var c=V(b,{parent:!0}).node;if(!c)throw new O(44);b=Ab(b);var d=ac(c,b);if(d)throw new O(d);if(!c.Na.symlink)throw new O(63);c.Na.symlink(c,b,a)} +function ta(a){var b=V(a,{parent:!0}).node,c=Ab(a),d=Ob(b,c),f=bc(b,c,!1);if(f)throw new O(f);if(!b.Na.unlink)throw new O(63);if(d.ab)throw new O(10);try{U.willDeletePath&&U.willDeletePath(a)}catch(g){J("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+g.message)}b.Na.unlink(b,c);Wb(d);try{if(U.onDeletePath)U.onDeletePath(a)}catch(g){J("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+g.message)}} +function Tb(a){a=V(a).node;if(!a)throw new O(44);if(!a.Na.readlink)throw new O(28);return Eb(Ub(a.parent),a.Na.readlink(a))}function jc(a,b){a=V(a,{Ya:!b}).node;if(!a)throw new O(44);if(!a.Na.Ua)throw new O(63);return a.Na.Ua(a)}function kc(a){return jc(a,!0)}function ea(a,b){var c;"string"===typeof a?c=V(a,{Ya:!0}).node:c=a;if(!c.Na.Ta)throw new O(63);c.Na.Ta(c,{mode:b&4095|c.mode&-4096,timestamp:Date.now()})} +function lc(a){var b;"string"===typeof a?b=V(a,{Ya:!0}).node:b=a;if(!b.Na.Ta)throw new O(63);b.Na.Ta(b,{timestamp:Date.now()})}function mc(a,b){if(0>b)throw new O(28);var c;"string"===typeof a?c=V(a,{Ya:!0}).node:c=a;if(!c.Na.Ta)throw new O(63);if(Q(c.mode))throw new O(31);if(32768!==(c.mode&61440))throw new O(28);if(a=Xb(c,"w"))throw new O(a);c.Na.Ta(c,{size:b,timestamp:Date.now()})} +function u(a,b,c,d){if(""===a)throw new O(44);if("string"===typeof b){var f=Zb[b];if("undefined"===typeof f)throw Error("Unknown file open mode: "+b);b=f}c=b&64?("undefined"===typeof c?438:c)&4095|32768:0;if("object"===typeof a)var g=a;else{a=r(a);try{g=V(a,{Ya:!(b&131072)}).node}catch(n){}}f=!1;if(b&64)if(g){if(b&128)throw new O(20);}else g=da(a,c,0),f=!0;if(!g)throw new O(44);8192===(g.mode&61440)&&(b&=-513);if(b&65536&&!Q(g.mode))throw new O(54);if(!f&&(c=g?40960===(g.mode&61440)?32:Q(g.mode)&& +("r"!==$b(b)||b&512)?31:Xb(g,$b(b)):44))throw new O(c);b&512&&mc(g,0);b&=-131713;d=dc({node:g,path:Ub(g),flags:b,seekable:!0,position:0,Oa:g.Oa,Rb:[],error:!1},d);d.Oa.open&&d.Oa.open(d);!e.logReadFiles||b&1||(Pc||(Pc={}),a in Pc||(Pc[a]=1,J("FS.trackingDelegate error on read file: "+a)));try{U.onOpenFile&&(g=0,1!==(b&2097155)&&(g|=1),0!==(b&2097155)&&(g|=2),U.onOpenFile(a,g))}catch(n){J("FS.trackingDelegate['onOpenFile']('"+a+"', flags) threw an exception: "+n.message)}return d} +function ka(a){if(null===a.fd)throw new O(8);a.ob&&(a.ob=null);try{a.Oa.close&&a.Oa.close(a)}catch(b){throw b;}finally{S[a.fd]=null}a.fd=null}function Qc(a,b,c){if(null===a.fd)throw new O(8);if(!a.seekable||!a.Oa.Za)throw new O(70);if(0!=c&&1!=c&&2!=c)throw new O(28);a.position=a.Oa.Za(a,b,c);a.Rb=[]} +function Sc(a,b,c,d,f){if(0>d||0>f)throw new O(28);if(null===a.fd)throw new O(8);if(1===(a.flags&2097155))throw new O(8);if(Q(a.node.mode))throw new O(31);if(!a.Oa.read)throw new O(28);var g="undefined"!==typeof f;if(!g)f=a.position;else if(!a.seekable)throw new O(70);b=a.Oa.read(a,b,c,d,f);g||(a.position+=b);return b} +function fa(a,b,c,d,f,g){if(0>d||0>f)throw new O(28);if(null===a.fd)throw new O(8);if(0===(a.flags&2097155))throw new O(8);if(Q(a.node.mode))throw new O(31);if(!a.Oa.write)throw new O(28);a.seekable&&a.flags&1024&&Qc(a,0,2);var n="undefined"!==typeof f;if(!n)f=a.position;else if(!a.seekable)throw new O(70);b=a.Oa.write(a,b,c,d,f,g);n||(a.position+=b);try{if(a.path&&U.onWriteToFile)U.onWriteToFile(a.path)}catch(t){J("FS.trackingDelegate['onWriteToFile']('"+a.path+"') threw an exception: "+t.message)}return b} +function sa(a){var b={encoding:"binary"};b=b||{};b.flags=b.flags||"r";b.encoding=b.encoding||"binary";if("utf8"!==b.encoding&&"binary"!==b.encoding)throw Error('Invalid encoding type "'+b.encoding+'"');var c,d=u(a,b.flags);a=jc(a).size;var f=new Uint8Array(a);Sc(d,f,0,a,0);"utf8"===b.encoding?c=Va(f,0):"binary"===b.encoding&&(c=f);ka(d);return c} +function Tc(){O||(O=function(a,b){this.node=b;this.Qb=function(c){this.Pa=c};this.Qb(a);this.message="FS error"},O.prototype=Error(),O.prototype.constructor=O,[44].forEach(function(a){Nb[a]=new O(a);Nb[a].stack=""}))}var Uc;function ca(a,b){var c=0;a&&(c|=365);b&&(c|=146);return c} +function Vc(a,b,c){a=r("/dev/"+a);var d=ca(!!b,!!c);Wc||(Wc=64);var f=Wc++<<8|0;Hb(f,{open:function(g){g.seekable=!1},close:function(){c&&c.buffer&&c.buffer.length&&c(10)},read:function(g,n,t,w){for(var v=0,C=0;C>2]=d.dev;L[c+4>>2]=0;L[c+8>>2]=d.ino;L[c+12>>2]=d.mode;L[c+16>>2]=d.nlink;L[c+20>>2]=d.uid;L[c+24>>2]=d.gid;L[c+28>>2]=d.rdev;L[c+32>>2]=0;M=[d.size>>>0,(N=d.size,1<=+Math.abs(N)?0>>0:~~+Math.ceil((N-+(~~N>>>0))/4294967296)>>>0:0)];L[c+40>>2]=M[0];L[c+44>>2]=M[1];L[c+48>>2]=4096;L[c+52>>2]=d.blocks;L[c+56>>2]=d.atime.getTime()/1E3|0;L[c+60>>2]= +0;L[c+64>>2]=d.mtime.getTime()/1E3|0;L[c+68>>2]=0;L[c+72>>2]=d.ctime.getTime()/1E3|0;L[c+76>>2]=0;M=[d.ino>>>0,(N=d.ino,1<=+Math.abs(N)?0>>0:~~+Math.ceil((N-+(~~N>>>0))/4294967296)>>>0:0)];L[c+80>>2]=M[0];L[c+84>>2]=M[1];return 0}var Zc=void 0;function $c(){Zc+=4;return L[Zc-4>>2]}function Z(a){a=S[a];if(!a)throw new O(8);return a}var ad={}; +function bd(){if(!cd){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"===typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:xa||"./this.program"},b;for(b in ad)a[b]=ad[b];var c=[];for(b in a)c.push(b+"="+a[b]);cd=c}return cd}var cd,dd;za?dd=function(){var a=process.hrtime();return 1E3*a[0]+a[1]/1E6}:"undefined"!==typeof dateNow?dd=dateNow:dd=function(){return performance.now()}; +function ed(a){for(var b=dd();dd()-b>2]);L[b>>2]=a.getSeconds();L[b+4>>2]=a.getMinutes();L[b+8>>2]=a.getHours();L[b+12>>2]=a.getDate();L[b+16>>2]=a.getMonth();L[b+20>>2]=a.getFullYear()-1900;L[b+24>>2]=a.getDay();var c=new Date(a.getFullYear(),0,1);L[b+28>>2]=(a.getTime()-c.getTime())/864E5|0;L[b+36>>2]=-(60*a.getTimezoneOffset());var d=(new Date(a.getFullYear(),6,1)).getTimezoneOffset(); +c=c.getTimezoneOffset();a=(d!=c&&a.getTimezoneOffset()==Math.min(c,d))|0;L[b+32>>2]=a;a=L[xb()+(a?4:0)>>2];L[b+40>>2]=a;return b},j:function(a,b){try{a=A(a);if(b&-8)var c=-28;else{var d;(d=V(a,{Ya:!0}).node)?(a="",b&4&&(a+="r"),b&2&&(a+="w"),b&1&&(a+="x"),c=a&&Xb(d,a)?-2:0):c=-44}return c}catch(f){return"undefined"!==typeof X&&f instanceof O||K(f),-f.Pa}},v:function(a,b){try{return a=A(a),ea(a,b),0}catch(c){return"undefined"!==typeof X&&c instanceof O||K(c),-c.Pa}},D:function(a){try{return a=A(a), +lc(a),0}catch(b){return"undefined"!==typeof X&&b instanceof O||K(b),-b.Pa}},w:function(a,b){try{var c=S[a];if(!c)throw new O(8);ea(c.node,b);return 0}catch(d){return"undefined"!==typeof X&&d instanceof O||K(d),-d.Pa}},E:function(a){try{var b=S[a];if(!b)throw new O(8);lc(b.node);return 0}catch(c){return"undefined"!==typeof X&&c instanceof O||K(c),-c.Pa}},c:function(a,b,c){Zc=c;try{var d=Z(a);switch(b){case 0:var f=$c();return 0>f?-28:u(d.path,d.flags,0,f).fd;case 1:case 2:return 0;case 3:return d.flags; +case 4:return f=$c(),d.flags|=f,0;case 12:return f=$c(),La[f+0>>1]=2,0;case 13:case 14:return 0;case 16:case 8:return-28;case 9:return Bb(28),-1;default:return-28}}catch(g){return"undefined"!==typeof X&&g instanceof O||K(g),-g.Pa}},x:function(a,b){try{var c=Z(a);return Yc(jc,c.path,b)}catch(d){return"undefined"!==typeof X&&d instanceof O||K(d),-d.Pa}},i:function(a,b,c){try{var d=S[a];if(!d)throw new O(8);if(0===(d.flags&2097155))throw new O(28);mc(d.node,c);return 0}catch(f){return"undefined"!==typeof X&& +f instanceof O||K(f),-f.Pa}},J:function(a,b){try{if(0===b)return-28;if(b=c)var d=-28;else{var f=Tb(a),g=Math.min(c,aa(f)),n=z[b+g];k(f,m,b,c+1);z[b+g]=n;d=g}return d}catch(t){return"undefined"!==typeof X&&t instanceof O||K(t),-t.Pa}},C:function(a){try{a=A(a);var b=V(a,{parent:!0}).node,c=Ab(a),d=Ob(b,c),f=bc(b,c,!0);if(f)throw new O(f);if(!b.Na.rmdir)throw new O(63);if(d.ab)throw new O(10);try{U.willDeletePath&&U.willDeletePath(a)}catch(g){J("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+ +g.message)}b.Na.rmdir(b,c);Wb(d);try{if(U.onDeletePath)U.onDeletePath(a)}catch(g){J("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+g.message)}return 0}catch(g){return"undefined"!==typeof X&&g instanceof O||K(g),-g.Pa}},f:function(a,b){try{return a=A(a),Yc(jc,a,b)}catch(c){return"undefined"!==typeof X&&c instanceof O||K(c),-c.Pa}},H:function(a){try{return a=A(a),ta(a),0}catch(b){return"undefined"!==typeof X&&b instanceof O||K(b),-b.Pa}},n:function(a,b,c){m.copyWithin(a,b,b+c)}, +d:function(a){a>>>=0;var b=m.length;if(2147483648=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);d=Math.max(16777216,a,d);0>>16);Ya(Oa.buffer);var f=1;break a}catch(g){}f=void 0}if(f)return!0}return!1},p:function(a,b){var c=0;bd().forEach(function(d,f){var g=b+c;f=L[a+4*f>>2]=g;for(g=0;g>0]=d.charCodeAt(g);z[f>>0]=0;c+=d.length+1});return 0},q:function(a,b){var c= +bd();L[a>>2]=c.length;var d=0;c.forEach(function(f){d+=f.length+1});L[b>>2]=d;return 0},g:function(a){try{var b=Z(a);ka(b);return 0}catch(c){return"undefined"!==typeof X&&c instanceof O||K(c),c.Pa}},o:function(a,b){try{var c=Z(a);z[b>>0]=c.tty?2:Q(c.mode)?3:40960===(c.mode&61440)?7:4;return 0}catch(d){return"undefined"!==typeof X&&d instanceof O||K(d),d.Pa}},m:function(a,b,c,d,f){try{var g=Z(a);a=4294967296*c+(b>>>0);if(-9007199254740992>=a||9007199254740992<=a)return-61;Qc(g,a,d);M=[g.position>>> +0,(N=g.position,1<=+Math.abs(N)?0>>0:~~+Math.ceil((N-+(~~N>>>0))/4294967296)>>>0:0)];L[f>>2]=M[0];L[f+4>>2]=M[1];g.ob&&0===a&&0===d&&(g.ob=null);return 0}catch(n){return"undefined"!==typeof X&&n instanceof O||K(n),n.Pa}},K:function(a){try{var b=Z(a);return b.Oa&&b.Oa.fsync?-b.Oa.fsync(b):0}catch(c){return"undefined"!==typeof X&&c instanceof O||K(c),c.Pa}},I:function(a,b,c,d){try{a:{for(var f=Z(a),g=a=0;g>2],L[b+(8* +g+4)>>2],void 0);if(0>n){var t=-1;break a}a+=n}t=a}L[d>>2]=t;return 0}catch(w){return"undefined"!==typeof X&&w instanceof O||K(w),w.Pa}},h:function(a){var b=Date.now();L[a>>2]=b/1E3|0;L[a+4>>2]=b%1E3*1E3|0;return 0},a:Oa,k:function(a,b){if(0===a)return Bb(28),-1;var c=L[a>>2];a=L[a+4>>2];if(0>a||999999999c)return Bb(28),-1;0!==b&&(L[b>>2]=0,L[b+4>>2]=0);return ed(1E6*c+a/1E3)},B:function(a){switch(a){case 30:return 16384;case 85:return 131072;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:case 79:return 200809; +case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32; +case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1E3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:return"object"===typeof navigator?navigator.hardwareConcurrency||1:1}Bb(28);return-1}, +L:function(a){var b=Date.now()/1E3|0;a&&(L[a>>2]=b);return b},s:function(a,b){if(b){var c=1E3*L[b+8>>2];c+=L[b+12>>2]/1E3}else c=Date.now();a=A(a);try{b=c;var d=V(a,{Ya:!0}).node;d.Na.Ta(d,{timestamp:Math.max(b,c)});return 0}catch(f){a=f;if(!(a instanceof O)){a+=" : ";a:{d=Error();if(!d.stack){try{throw Error();}catch(g){d=g}if(!d.stack){d="(no stack trace available)";break a}}d=d.stack.toString()}e.extraStackTrace&&(d+="\n"+e.extraStackTrace());d=ob(d);throw a+d;}Bb(a.Pa);return-1}}}; +(function(){function a(f){e.asm=f.exports;Ja=e.asm.M;eb--;e.monitorRunDependencies&&e.monitorRunDependencies(eb);0==eb&&(null!==fb&&(clearInterval(fb),fb=null),gb&&(f=gb,gb=null,f()))}function b(f){a(f.instance)}function c(f){return mb().then(function(g){return WebAssembly.instantiate(g,d)}).then(f,function(g){J("failed to asynchronously prepare wasm: "+g);K(g)})}var d={a:id};eb++;e.monitorRunDependencies&&e.monitorRunDependencies(eb);if(e.instantiateWasm)try{return e.instantiateWasm(d,a)}catch(f){return J("Module.instantiateWasm callback failed with error: "+ +f),!1}(function(){if(Ka||"function"!==typeof WebAssembly.instantiateStreaming||jb()||hb("file://")||"function"!==typeof fetch)return c(b);fetch(ib,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,d).then(b,function(g){J("wasm streaming compile failed: "+g);J("falling back to ArrayBuffer instantiation");return c(b)})})})();return{}})(); +var fd=e.___wasm_call_ctors=function(){return(fd=e.___wasm_call_ctors=e.asm.N).apply(null,arguments)},hd=e._memset=function(){return(hd=e._memset=e.asm.O).apply(null,arguments)};e._sqlite3_free=function(){return(e._sqlite3_free=e.asm.P).apply(null,arguments)};var Cb=e.___errno_location=function(){return(Cb=e.___errno_location=e.asm.Q).apply(null,arguments)};e._sqlite3_finalize=function(){return(e._sqlite3_finalize=e.asm.R).apply(null,arguments)}; +e._sqlite3_reset=function(){return(e._sqlite3_reset=e.asm.S).apply(null,arguments)};e._sqlite3_clear_bindings=function(){return(e._sqlite3_clear_bindings=e.asm.T).apply(null,arguments)};e._sqlite3_value_blob=function(){return(e._sqlite3_value_blob=e.asm.U).apply(null,arguments)};e._sqlite3_value_text=function(){return(e._sqlite3_value_text=e.asm.V).apply(null,arguments)};e._sqlite3_value_bytes=function(){return(e._sqlite3_value_bytes=e.asm.W).apply(null,arguments)}; +e._sqlite3_value_double=function(){return(e._sqlite3_value_double=e.asm.X).apply(null,arguments)};e._sqlite3_value_int=function(){return(e._sqlite3_value_int=e.asm.Y).apply(null,arguments)};e._sqlite3_value_type=function(){return(e._sqlite3_value_type=e.asm.Z).apply(null,arguments)};e._sqlite3_result_blob=function(){return(e._sqlite3_result_blob=e.asm._).apply(null,arguments)};e._sqlite3_result_double=function(){return(e._sqlite3_result_double=e.asm.$).apply(null,arguments)}; +e._sqlite3_result_error=function(){return(e._sqlite3_result_error=e.asm.aa).apply(null,arguments)};e._sqlite3_result_int=function(){return(e._sqlite3_result_int=e.asm.ba).apply(null,arguments)};e._sqlite3_result_int64=function(){return(e._sqlite3_result_int64=e.asm.ca).apply(null,arguments)};e._sqlite3_result_null=function(){return(e._sqlite3_result_null=e.asm.da).apply(null,arguments)};e._sqlite3_result_text=function(){return(e._sqlite3_result_text=e.asm.ea).apply(null,arguments)}; +e._sqlite3_step=function(){return(e._sqlite3_step=e.asm.fa).apply(null,arguments)};e._sqlite3_column_count=function(){return(e._sqlite3_column_count=e.asm.ga).apply(null,arguments)};e._sqlite3_data_count=function(){return(e._sqlite3_data_count=e.asm.ha).apply(null,arguments)};e._sqlite3_column_blob=function(){return(e._sqlite3_column_blob=e.asm.ia).apply(null,arguments)};e._sqlite3_column_bytes=function(){return(e._sqlite3_column_bytes=e.asm.ja).apply(null,arguments)}; +e._sqlite3_column_double=function(){return(e._sqlite3_column_double=e.asm.ka).apply(null,arguments)};e._sqlite3_column_text=function(){return(e._sqlite3_column_text=e.asm.la).apply(null,arguments)};e._sqlite3_column_type=function(){return(e._sqlite3_column_type=e.asm.ma).apply(null,arguments)};e._sqlite3_column_name=function(){return(e._sqlite3_column_name=e.asm.na).apply(null,arguments)};e._sqlite3_bind_blob=function(){return(e._sqlite3_bind_blob=e.asm.oa).apply(null,arguments)}; +e._sqlite3_bind_double=function(){return(e._sqlite3_bind_double=e.asm.pa).apply(null,arguments)};e._sqlite3_bind_int=function(){return(e._sqlite3_bind_int=e.asm.qa).apply(null,arguments)};e._sqlite3_bind_text=function(){return(e._sqlite3_bind_text=e.asm.ra).apply(null,arguments)};e._sqlite3_bind_parameter_index=function(){return(e._sqlite3_bind_parameter_index=e.asm.sa).apply(null,arguments)};e._sqlite3_sql=function(){return(e._sqlite3_sql=e.asm.ta).apply(null,arguments)}; +e._sqlite3_normalized_sql=function(){return(e._sqlite3_normalized_sql=e.asm.ua).apply(null,arguments)};e._sqlite3_errmsg=function(){return(e._sqlite3_errmsg=e.asm.va).apply(null,arguments)};e._sqlite3_exec=function(){return(e._sqlite3_exec=e.asm.wa).apply(null,arguments)};e._sqlite3_prepare_v2=function(){return(e._sqlite3_prepare_v2=e.asm.xa).apply(null,arguments)};e._sqlite3_changes=function(){return(e._sqlite3_changes=e.asm.ya).apply(null,arguments)}; +e._sqlite3_close_v2=function(){return(e._sqlite3_close_v2=e.asm.za).apply(null,arguments)};e._sqlite3_create_function_v2=function(){return(e._sqlite3_create_function_v2=e.asm.Aa).apply(null,arguments)};e._sqlite3_open=function(){return(e._sqlite3_open=e.asm.Ba).apply(null,arguments)};var ba=e._malloc=function(){return(ba=e._malloc=e.asm.Ca).apply(null,arguments)},na=e._free=function(){return(na=e._free=e.asm.Da).apply(null,arguments)}; +e._RegisterExtensionFunctions=function(){return(e._RegisterExtensionFunctions=e.asm.Ea).apply(null,arguments)}; +var xb=e.__get_tzname=function(){return(xb=e.__get_tzname=e.asm.Fa).apply(null,arguments)},vb=e.__get_daylight=function(){return(vb=e.__get_daylight=e.asm.Ga).apply(null,arguments)},ub=e.__get_timezone=function(){return(ub=e.__get_timezone=e.asm.Ha).apply(null,arguments)},oa=e.stackSave=function(){return(oa=e.stackSave=e.asm.Ia).apply(null,arguments)},qa=e.stackRestore=function(){return(qa=e.stackRestore=e.asm.Ja).apply(null,arguments)},y=e.stackAlloc=function(){return(y=e.stackAlloc=e.asm.Ka).apply(null, +arguments)},gd=e._memalign=function(){return(gd=e._memalign=e.asm.La).apply(null,arguments)};e.cwrap=function(a,b,c,d){c=c||[];var f=c.every(function(g){return"number"===g});return"string"!==b&&f&&!d?Qa(a):function(){return Ra(a,b,c,arguments)}};e.UTF8ToString=A;e.stackSave=oa;e.stackRestore=qa;e.stackAlloc=y;var jd;gb=function kd(){jd||ld();jd||(gb=kd)}; +function ld(){function a(){if(!jd&&(jd=!0,e.calledRun=!0,!Pa)){e.noFSInit||Uc||(Uc=!0,Tc(),e.stdin=e.stdin,e.stdout=e.stdout,e.stderr=e.stderr,e.stdin?Vc("stdin",e.stdin):ic("/dev/tty","/dev/stdin"),e.stdout?Vc("stdout",null,e.stdout):ic("/dev/tty","/dev/stdout"),e.stderr?Vc("stderr",null,e.stderr):ic("/dev/tty1","/dev/stderr"),u("/dev/stdin","r"),u("/dev/stdout","w"),u("/dev/stderr","w"));nb(ab);Sb=!1;nb(bb);if(e.onRuntimeInitialized)e.onRuntimeInitialized();if(e.postRun)for("function"==typeof e.postRun&& +(e.postRun=[e.postRun]);e.postRun.length;){var b=e.postRun.shift();cb.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 z¨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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart index f7fbc277b..6a34e4f09 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart @@ -1,5 +1,6 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/utils.dart'; @@ -43,10 +44,10 @@ class FileAttachment extends AttachmentWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - child: _getFileTypeImage(context), height: 40.0, width: 33.33, margin: EdgeInsets.all(8.0), + child: _getFileTypeImage(context), ), SizedBox(width: 8.0), Expanded( @@ -102,12 +103,15 @@ class FileAttachment extends AttachmentWidget { errorWidget: (_, obj, trace) { return getFileTypeImage(attachment.extraData['other']); }, - progressIndicatorBuilder: (context, _, progress) { - return Center( - child: Container( - width: 20.0, - height: 20.0, - child: const CircularProgressIndicator(), + placeholder: (_, __) { + return Shimmer.fromColors( + baseColor: StreamChatTheme.of(context).colorTheme.greyGainsboro, + highlightColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, + child: Image.asset( + 'images/placeholder.png', + fit: BoxFit.cover, + package: 'stream_chat_flutter', ), ); }, diff --git a/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart index 8247661c2..392ada7c7 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart @@ -1,5 +1,6 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; import '../full_screen_media.dart'; @@ -139,6 +140,7 @@ class GiphyAttachment extends AttachmentWidget { Card( color: Colors.white, elevation: 2, + shape: CircleBorder(), child: IconButton( padding: const EdgeInsets.all(0), constraints: BoxConstraints.tight(Size(32, 32)), @@ -152,7 +154,6 @@ class GiphyAttachment extends AttachmentWidget { }); }, ), - shape: CircleBorder(), ), Expanded( child: Center( @@ -167,6 +168,7 @@ class GiphyAttachment extends AttachmentWidget { Card( color: Colors.white, elevation: 2, + shape: CircleBorder(), child: IconButton( padding: const EdgeInsets.all(0), constraints: BoxConstraints.tight(Size(32, 32)), @@ -180,7 +182,6 @@ class GiphyAttachment extends AttachmentWidget { }); }, ), - shape: CircleBorder(), ), ], ), @@ -345,11 +346,15 @@ class GiphyAttachment extends AttachmentWidget { height: size?.height, width: size?.width, placeholder: (_, __) { - return Container( - width: size?.width, - height: size?.height, - child: Center( - child: CircularProgressIndicator(), + return Shimmer.fromColors( + baseColor: + StreamChatTheme.of(context).colorTheme.greyGainsboro, + highlightColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, + child: Image.asset( + 'images/placeholder.png', + fit: BoxFit.cover, + package: 'stream_chat_flutter', ), ); }, diff --git a/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart index d4b70dd64..98509bb90 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart @@ -1,5 +1,6 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; import 'package:stream_chat_flutter/src/attachment/attachment_upload_state_builder.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; @@ -51,22 +52,46 @@ class ImageAttachment extends AttachmentWidget { ); }, network: () { - final imageUrl = + var imageUrl = attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl; + if (imageUrl == null) { return AttachmentError(size: size); } + + var imageUri = Uri.parse(imageUrl); + if (imageUri.host == 'stream-io-cdn.com') { + imageUri = imageUri.replace(queryParameters: { + ...imageUri.queryParameters, + 'h': '500', + 'w': '500', + 'crop': 'center', + 'resize': 'crop', + }); + } else if (imageUri.host == 'stream-cloud-uploads.imgix.net') { + imageUri = imageUri.replace(queryParameters: { + ...imageUri.queryParameters, + 'height': '500', + 'width': '500', + 'fit': 'crop', + }); + } + imageUrl = imageUri.toString(); + return _buildImageAttachment( context, CachedNetworkImage( height: size?.height, width: size?.width, placeholder: (_, __) { - return Container( - width: size?.width, - height: size?.height, - child: Center( - child: CircularProgressIndicator(), + return Shimmer.fromColors( + baseColor: StreamChatTheme.of(context).colorTheme.greyGainsboro, + highlightColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, + child: Image.asset( + 'images/placeholder.png', + fit: BoxFit.cover, + package: 'stream_chat_flutter', ), ); }, diff --git a/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart index b7a454560..d2ffc3357 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart @@ -11,6 +11,7 @@ class VideoAttachment extends AttachmentWidget { final MessageTheme messageTheme; final ShowMessageCallback onShowMessage; final ValueChanged onReturnAction; + final VoidCallback onAttachmentTap; const VideoAttachment({ Key key, @@ -20,6 +21,7 @@ class VideoAttachment extends AttachmentWidget { this.messageTheme, this.onShowMessage, this.onReturnAction, + this.onAttachmentTap, }) : super(key: key, message: message, attachment: attachment, size: size); @override @@ -65,25 +67,26 @@ class VideoAttachment extends AttachmentWidget { children: [ Expanded( child: GestureDetector( - onTap: () async { - final channel = StreamChannel.of(context).channel; - final res = await Navigator.push( - context, - MaterialPageRoute( - builder: (_) => StreamChannel( - channel: channel, - child: FullScreenMedia( - mediaAttachments: [attachment], - userName: message.user.name, - sentAt: message.createdAt, - message: message, - onShowMessage: onShowMessage, + onTap: onAttachmentTap ?? + () async { + final channel = StreamChannel.of(context).channel; + final res = await Navigator.push( + context, + MaterialPageRoute( + builder: (_) => StreamChannel( + channel: channel, + child: FullScreenMedia( + mediaAttachments: [attachment], + userName: message.user.name, + sentAt: message.createdAt, + message: message, + onShowMessage: onShowMessage, + ), + ), ), - ), - ), - ); - if (res != null) onReturnAction(res); - }, + ); + if (res != null) onReturnAction(res); + }, child: Stack( children: [ videoWidget, diff --git a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart new file mode 100644 index 000000000..d9b9c016a --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart @@ -0,0 +1,324 @@ +import 'dart:ui'; + +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:image_gallery_saver/image_gallery_saver.dart'; +import 'package:path_provider/path_provider.dart'; + +import '../stream_chat_flutter.dart'; +import 'extension.dart'; + +/// Callback to download an attachment asset +typedef AttachmentDownloader = Future Function( + Attachment attachment, { + ProgressCallback progressCallback, +}); + +/// Widget that shows the options in the gallery view +class AttachmentActionsModal extends StatelessWidget { + /// The message containing the attachments + final Message message; + + /// Current page index + final currentIndex; + + /// Callback to show the message + final VoidCallback onShowMessage; + + /// Callback to download images + final AttachmentDownloader imageDownloader; + + /// Callback to provide download files + final AttachmentDownloader fileDownloader; + + /// Returns a new [AttachmentActionsModal] + const AttachmentActionsModal({ + this.message, + this.currentIndex, + this.onShowMessage, + this.imageDownloader, + this.fileDownloader, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => Navigator.maybePop(context), + child: _buildPage(context), + ); + } + + Widget _buildPage(context) { + final theme = StreamChatTheme.of(context); + return Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SizedBox(height: kToolbarHeight), + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Container( + width: MediaQuery.of(context).size.width * 0.5, + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16.0), + ), + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + _buildButton( + context, + 'Reply', + StreamSvgIcon.iconCurveLineLeftUp( + size: 24.0, + color: theme.colorTheme.grey, + ), + () { + Navigator.pop(context, ReturnActionType.reply); + }, + ), + _buildButton( + context, + 'Show in Chat', + StreamSvgIcon.eye( + size: 24.0, + color: theme.colorTheme.black, + ), + onShowMessage, + ), + _buildButton( + context, + 'Save ${message.attachments[currentIndex].type == 'video' ? 'Video' : 'Image'}', + StreamSvgIcon.iconSave( + size: 24.0, + color: theme.colorTheme.grey, + ), + () { + final attachment = message.attachments[currentIndex]; + final isImage = attachment.type == 'image'; + final saveFile = fileDownloader ?? _downloadAttachment; + final saveImage = imageDownloader ?? _downloadAttachment; + final downloader = isImage ? saveImage : saveFile; + + final progressNotifier = ValueNotifier<_DownloadProgress>( + _DownloadProgress.initial(), + ); + + downloader( + attachment, + progressCallback: (received, total) { + progressNotifier.value = _DownloadProgress( + total, + received, + ); + }, + ).catchError((_) { + progressNotifier.value = null; + }); + + // Closing attachment actions modal before opening + // attachment download dialog + Navigator.pop(context); + + showDialog( + barrierDismissible: false, + context: context, + barrierColor: theme.colorTheme.overlay, + builder: (context) => _buildDownloadProgressDialog( + context, + progressNotifier, + ), + ); + }, + ), + if (StreamChat.of(context).user.id == message.user.id) + _buildButton( + context, + 'Delete', + StreamSvgIcon.delete( + size: 24.0, + color: theme.colorTheme.accentRed, + ), + () { + final channel = StreamChannel.of(context).channel; + if (message.attachments.length > 1 || + message.text.isNotEmpty) { + final remainingAttachments = [...message.attachments] + ..removeAt(currentIndex); + channel.updateMessage(message.copyWith( + attachments: remainingAttachments, + )); + Navigator.pop(context); + Navigator.pop(context); + } else { + channel.deleteMessage(message).then((value) { + Navigator.pop(context); + Navigator.pop(context); + }); + } + }, + color: theme.colorTheme.accentRed, + ), + ] + .map((e) => + Align(alignment: Alignment.centerRight, child: e)) + .insertBetween( + Container( + height: 1, + color: theme.colorTheme.greyWhisper, + ), + ), + ), + ), + ), + ) + ], + ); + } + + Widget _buildButton( + context, + String title, + StreamSvgIcon icon, + VoidCallback onTap, { + Color color, + }) { + return Material( + color: StreamChatTheme.of(context).colorTheme.white, + child: InkWell( + onTap: onTap, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), + child: Row( + children: [ + icon, + SizedBox(width: 16), + Text( + title, + style: StreamChatTheme.of(context) + .textTheme + .body + .copyWith(color: color), + ), + ], + ), + ), + ), + ); + } + + Widget _buildDownloadProgressDialog( + BuildContext context, + ValueNotifier<_DownloadProgress> progressNotifier, + ) { + final theme = StreamChatTheme.of(context); + return WillPopScope( + onWillPop: () => Future.value(false), + child: ValueListenableBuilder( + valueListenable: progressNotifier, + builder: (_, _DownloadProgress progress, __) { + // Pop the dialog in case the progress is null or it's completed. + if (progress == null || progress?.toProgressIndicatorValue == 1.0) { + Future.delayed( + const Duration(milliseconds: 500), + Navigator.of(context).pop, + ); + } + return Material( + type: MaterialType.transparency, + child: Center( + child: Container( + height: 182, + width: 182, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + color: theme.colorTheme.white, + ), + child: Center( + child: progress == null + ? Container( + height: 100, + width: 100, + child: StreamSvgIcon.error( + color: theme.colorTheme.greyGainsboro, + ), + ) + : progress.toProgressIndicatorValue == 1.0 + ? Container( + height: 160, + width: 160, + child: StreamSvgIcon.check( + color: theme.colorTheme.greyGainsboro, + ), + ) + : Container( + height: 100, + width: 100, + child: Stack( + fit: StackFit.expand, + children: [ + CircularProgressIndicator( + value: progress.toProgressIndicatorValue, + strokeWidth: 8.0, + valueColor: AlwaysStoppedAnimation( + theme.colorTheme.accentBlue, + ), + ), + Center( + child: Text( + '${progress.toPercentage}%', + style: theme.textTheme.headline.copyWith( + color: theme.colorTheme.grey, + ), + ), + ), + ], + ), + ), + ), + ), + ), + ); + }, + ), + ); + } + + Future _downloadAttachment( + Attachment attachment, { + ProgressCallback progressCallback, + }) async { + String filePath; + final appDocDir = await getTemporaryDirectory(); + await Dio().download( + attachment.assetUrl ?? attachment.imageUrl ?? attachment.thumbUrl, + (Headers responseHeaders) { + final contentType = responseHeaders[Headers.contentTypeHeader]; + final mimeType = contentType.first?.split('/')?.last; + filePath ??= '${appDocDir.path}/${attachment.id}.$mimeType'; + return filePath; + }, + onReceiveProgress: progressCallback, + ); + final result = await ImageGallerySaver.saveFile(filePath); + return (result as Map)['filePath']; + } +} + +class _DownloadProgress { + final int total; + final int received; + + const _DownloadProgress(this.total, this.received); + + factory _DownloadProgress.initial() { + return _DownloadProgress(double.maxFinite.toInt(), 0); + } + + double get toProgressIndicatorValue => received / total; + + int get toPercentage => (received * 100) ~/ total; +} diff --git a/packages/stream_chat_flutter/lib/src/back_button.dart b/packages/stream_chat_flutter/lib/src/back_button.dart index 9d7875176..f49fa98cb 100644 --- a/packages/stream_chat_flutter/lib/src/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/back_button.dart @@ -21,28 +21,28 @@ class StreamBackButton extends StatelessWidget { @override Widget build(BuildContext context) { return Stack( + alignment: Alignment.center, children: [ - Padding( + RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + elevation: 0, + highlightElevation: 0, + focusElevation: 0, + disabledElevation: 0, + hoverElevation: 0, + onPressed: () { + if (onPressed != null) { + onPressed(); + } else { + Navigator.maybePop(context); + } + }, padding: const EdgeInsets.all(14.0), - child: RawMaterialButton( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), - elevation: 0, - highlightElevation: 0, - focusElevation: 0, - disabledElevation: 0, - hoverElevation: 0, - onPressed: () { - if (onPressed != null) { - onPressed(); - } else { - Navigator.maybePop(context); - } - }, - child: StreamSvgIcon.left( - size: 24, - color: StreamChatTheme.of(context).colorTheme.black, - ), + child: StreamSvgIcon.left( + size: 24, + color: StreamChatTheme.of(context).colorTheme.black, ), ), if (showUnreads) diff --git a/packages/stream_chat_flutter/lib/src/channel_bottom_sheet.dart b/packages/stream_chat_flutter/lib/src/channel_bottom_sheet.dart index 57b27a2fd..2f3a26b27 100644 --- a/packages/stream_chat_flutter/lib/src/channel_bottom_sheet.dart +++ b/packages/stream_chat_flutter/lib/src/channel_bottom_sheet.dart @@ -114,9 +114,9 @@ class _ChannelBottomSheetState extends State { children: [ UserAvatar( user: members[index].user, - constraints: BoxConstraints( - maxHeight: 64.0, - maxWidth: 64.0, + constraints: BoxConstraints.tightFor( + height: 64.0, + width: 64.0, ), borderRadius: BorderRadius.circular(32.0), onlineIndicatorConstraints: @@ -238,8 +238,8 @@ class _ChannelBottomSheetState extends State { color: StreamChatTheme.of(context).colorTheme.accentRed, ), ); - var channel = StreamChannel.of(context).channel; if (res == true) { + final channel = StreamChannel.of(context).channel; await channel.removeMembers([StreamChat.of(context).user.id]); Navigator.pop(context); } diff --git a/packages/stream_chat_flutter/lib/src/channel_file_display_screen.dart b/packages/stream_chat_flutter/lib/src/channel_file_display_screen.dart index a6be5555b..2813f300b 100644 --- a/packages/stream_chat_flutter/lib/src/channel_file_display_screen.dart +++ b/packages/stream_chat_flutter/lib/src/channel_file_display_screen.dart @@ -71,12 +71,12 @@ class _ChannelFileDisplayScreenState extends State { Navigator.of(context).pop(); }, child: Container( + width: 24.0, + height: 24.0, child: StreamSvgIcon.left( color: StreamChatTheme.of(context).colorTheme.black, size: 24.0, ), - width: 24.0, - height: 24.0, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index 6845a6324..c2927a6ee 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -71,6 +71,19 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { final bool showConnectionStateTile; + /// Title widget + final Widget title; + + /// Subtitle widget + final Widget subtitle; + + /// Leading widget + final Widget leading; + + /// AppBar actions + /// By default it shows the [ChannelImage] + final List actions; + /// Creates a channel header ChannelHeader({ Key key, @@ -80,6 +93,10 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { this.showTypingIndicator = true, this.onImageTap, this.showConnectionStateTile = false, + this.title, + this.subtitle, + this.leading, + this.actions, }) : preferredSize = Size.fromHeight(kToolbarHeight), super(key: key); @@ -87,6 +104,14 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { Widget build(BuildContext context) { final channel = StreamChannel.of(context).channel; + final leadingWidget = leading ?? + (showBackButton + ? StreamBackButton( + onPressed: onBackPressed, + showUnreads: true, + ) + : SizedBox()); + return ConnectionStatusBuilder( statusBuilder: (context, status) { var statusString = ''; @@ -111,26 +136,32 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { child: AppBar( brightness: Theme.of(context).brightness, elevation: 1, - leading: showBackButton - ? StreamBackButton( - onPressed: onBackPressed, - showUnreads: true, - ) - : SizedBox(), + leading: leadingWidget, backgroundColor: StreamChatTheme.of(context) .channelTheme .channelHeaderTheme .color, - actions: [ - Padding( - padding: const EdgeInsets.only(right: 10.0), - child: Center( - child: ChannelImage( - onTap: onImageTap, + actions: actions ?? + [ + Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Center( + child: ChannelImage( + borderRadius: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .avatarTheme + .borderRadius, + constraints: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .avatarTheme + .constraints, + onTap: onImageTap, + ), + ), ), - ), - ), - ], + ], centerTitle: true, title: InkWell( onTap: onTitleTap, @@ -141,20 +172,23 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - ChannelName( - textStyle: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .title, - ), + title ?? + ChannelName( + textStyle: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .title, + ), SizedBox(height: 2), - ChannelInfo( - showTypingIndicator: showTypingIndicator, - channel: channel, - textStyle: StreamChatTheme.of(context) - .channelPreviewTheme - .subtitle, - ), + subtitle ?? + ChannelInfo( + showTypingIndicator: showTypingIndicator, + channel: channel, + textStyle: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .subtitle, + ), ], ), ), diff --git a/packages/stream_chat_flutter/lib/src/channel_image.dart b/packages/stream_chat_flutter/lib/src/channel_image.dart index 649a58808..e7e39d385 100644 --- a/packages/stream_chat_flutter/lib/src/channel_image.dart +++ b/packages/stream_chat_flutter/lib/src/channel_image.dart @@ -96,7 +96,11 @@ class ChannelImage extends StatelessWidget { initialData: otherMember.user, builder: (context, snapshot) { return UserAvatar( - borderRadius: borderRadius, + borderRadius: borderRadius ?? + StreamChatTheme.of(context) + .channelPreviewTheme + .avatarTheme + .borderRadius, user: snapshot.data ?? otherMember.user, constraints: constraints ?? StreamChatTheme.of(context) @@ -120,7 +124,11 @@ class ChannelImage extends StatelessWidget { .toList(); return GroupImage( images: images, - borderRadius: borderRadius, + borderRadius: borderRadius ?? + StreamChatTheme.of(context) + .channelPreviewTheme + .avatarTheme + .borderRadius, constraints: constraints ?? StreamChatTheme.of(context) .channelPreviewTheme diff --git a/packages/stream_chat_flutter/lib/src/channel_info.dart b/packages/stream_chat_flutter/lib/src/channel_info.dart index 53a621a03..1d6f6fe27 100644 --- a/packages/stream_chat_flutter/lib/src/channel_info.dart +++ b/packages/stream_chat_flutter/lib/src/channel_info.dart @@ -57,7 +57,7 @@ class ChannelInfo extends StatelessWidget { style: StreamChatTheme.of(context) .channelTheme .channelHeaderTheme - .lastMessageAt, + .subtitle, ); } else { final otherMember = members.firstWhere( @@ -69,10 +69,7 @@ class ChannelInfo extends StatelessWidget { if (otherMember.user.online) { alternativeWidget = Text( 'Online', - style: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .lastMessageAt, + style: textStyle, ); } else { alternativeWidget = Text( diff --git a/packages/stream_chat_flutter/lib/src/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel_list_header.dart index cca4170ec..88b329e69 100644 --- a/packages/stream_chat_flutter/lib/src/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_list_header.dart @@ -45,7 +45,7 @@ typedef _TitleBuilder = Widget Function( /// The widget by default uses the inherited [StreamChatClient] to fetch information about the status. /// However you can also pass your own [StreamChatClient] if you don't have it in the widget tree. /// -/// The widget components render the ui based on the first ancestor of type [StreamChatTheme] and on its [ChannelTheme.channelHeaderTheme] property. +/// The widget components render the ui based on the first ancestor of type [StreamChatTheme] and on its [ChannelListHeaderTheme] property. /// Modify it to change the widget appearance. class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { /// Instantiates a ChannelListHeader @@ -57,6 +57,9 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { this.onNewChatButtonTap, this.showConnectionStateTile = false, this.preNavigationCallback, + this.subtitle, + this.leading, + this.actions, }) : super(key: key); /// Pass this if you don't have a [StreamChatClient] in your widget tree. @@ -76,6 +79,17 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { final VoidCallback preNavigationCallback; + /// Subtitle widget + final Widget subtitle; + + /// Leading widget + /// By default it shows the logged in user avatar + final Widget leading; + + /// AppBar actions + /// By default it shows the new chat button + final List actions; + @override Widget build(BuildContext context) { final _client = client ?? StreamChat.of(context).client; @@ -104,76 +118,85 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { child: AppBar( brightness: Theme.of(context).brightness, elevation: 1, - backgroundColor: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .color, + backgroundColor: + StreamChatTheme.of(context).channelListHeaderTheme.color, centerTitle: true, - leading: Center( - child: UserAvatar( - user: user, - showOnlineStatus: false, - onTap: onUserAvatarTap ?? - (_) { - if (preNavigationCallback != null) { - preNavigationCallback(); - } - Scaffold.of(context).openDrawer(); - }, - borderRadius: BorderRadius.circular(20), - constraints: BoxConstraints.tightFor( - height: 40, - width: 40, - ), - ), - ), - actions: [ - StreamNeumorphicButton( - child: IconButton( - icon: ConnectionStatusBuilder( - statusBuilder: (context, status) { - var color; - switch (status) { - case ConnectionStatus.connected: - color = - StreamChatTheme.of(context).colorTheme.accentBlue; - break; - case ConnectionStatus.connecting: - color = Colors.grey; - break; - case ConnectionStatus.disconnected: - color = Colors.grey; - break; - } - return SvgPicture.asset( - 'svgs/icon_pen_write.svg', - package: 'stream_chat_flutter', - width: 24.0, - height: 24.0, - color: color, - ); - }, + leading: leading ?? + Center( + child: UserAvatar( + user: user, + showOnlineStatus: false, + onTap: onUserAvatarTap ?? + (_) { + if (preNavigationCallback != null) { + preNavigationCallback(); + } + Scaffold.of(context).openDrawer(); + }, + borderRadius: StreamChatTheme.of(context) + .channelListHeaderTheme + .avatarTheme + .borderRadius, + constraints: StreamChatTheme.of(context) + .channelListHeaderTheme + .avatarTheme + .constraints, ), - onPressed: onNewChatButtonTap, ), - ) - ], - title: Builder( - builder: (context) { - if (titleBuilder != null) { - return titleBuilder(context, status, _client); - } - switch (status) { - case ConnectionStatus.connected: - return _buildConnectedTitleState(context); - case ConnectionStatus.connecting: - return _buildConnectingTitleState(context); - case ConnectionStatus.disconnected: - return _buildDisconnectedTitleState(context, _client); - default: - return Offstage(); - } - }, + actions: actions ?? + [ + StreamNeumorphicButton( + child: IconButton( + icon: ConnectionStatusBuilder( + statusBuilder: (context, status) { + var color; + switch (status) { + case ConnectionStatus.connected: + color = StreamChatTheme.of(context) + .colorTheme + .accentBlue; + break; + case ConnectionStatus.connecting: + color = Colors.grey; + break; + case ConnectionStatus.disconnected: + color = Colors.grey; + break; + } + return SvgPicture.asset( + 'svgs/icon_pen_write.svg', + package: 'stream_chat_flutter', + width: 24.0, + height: 24.0, + color: color, + ); + }, + ), + onPressed: onNewChatButtonTap, + ), + ) + ], + title: Column( + children: [ + Builder( + builder: (context) { + if (titleBuilder != null) { + return titleBuilder(context, status, _client); + } + switch (status) { + case ConnectionStatus.connected: + return _buildConnectedTitleState(context); + case ConnectionStatus.connecting: + return _buildConnectingTitleState(context); + case ConnectionStatus.disconnected: + return _buildDisconnectedTitleState(context, _client); + default: + return Offstage(); + } + }, + ), + subtitle ?? Offstage(), + ], ), ), ); @@ -202,14 +225,11 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { SizedBox(width: 10), Text( 'Searching for Network', - style: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .title - .copyWith( - fontSize: 16, - fontWeight: FontWeight.bold, - ), + style: + StreamChatTheme.of(context).channelListHeaderTheme.title.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + ), ), ], ); @@ -222,14 +242,11 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { children: [ Text( 'Offline...', - style: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .title - .copyWith( - fontSize: 16, - fontWeight: FontWeight.bold, - ), + style: + StreamChatTheme.of(context).channelListHeaderTheme.title.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + ), ), TextButton( onPressed: () async { @@ -239,8 +256,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { child: Text( 'Try Again', style: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme + .channelListHeaderTheme .title .copyWith( fontSize: 16, diff --git a/packages/stream_chat_flutter/lib/src/channel_list_view.dart b/packages/stream_chat_flutter/lib/src/channel_list_view.dart index 1fb9885a9..0396bffed 100644 --- a/packages/stream_chat_flutter/lib/src/channel_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/channel_list_view.dart @@ -223,8 +223,8 @@ class _ChannelListViewState extends State { } return AnimatedSwitcher( - child: child, duration: const Duration(milliseconds: 500), + child: child, ); } @@ -393,16 +393,17 @@ class _ChannelListViewState extends State { subtitle: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Align( - alignment: Alignment.centerLeft, - child: Container( - decoration: BoxDecoration( - color: StreamChatTheme.of(context).colorTheme.white, - borderRadius: BorderRadius.circular(11), - ), - constraints: BoxConstraints.tightFor( - height: 16, - width: 238, + Expanded( + child: Align( + alignment: Alignment.centerLeft, + child: Container( + decoration: BoxDecoration( + color: StreamChatTheme.of(context).colorTheme.white, + borderRadius: BorderRadius.circular(11), + ), + constraints: BoxConstraints.expand( + height: 16, + ), ), ), ), @@ -468,8 +469,8 @@ class _ChannelListViewState extends State { MaterialPageRoute( builder: (context) { return StreamChannel( - child: widget.channelWidget, channel: client, + child: widget.channelWidget, ); }, ), @@ -505,12 +506,12 @@ class _ChannelListViewState extends State { context: context, builder: (context) { return StreamChannel( + channel: channel, child: ChannelBottomSheet( onViewInfoTap: () { widget.onViewInfoTap(channel); }, ), - channel: channel, ); }, ); @@ -553,7 +554,7 @@ class _ChannelListViewState extends State { ChannelPreview( onLongPress: widget.onChannelLongPress, channel: channel, - onImageTap: widget.onImageTap?.call(channel), + onImageTap: () => widget.onImageTap?.call(channel), onTap: (channel) => onTap(channel, widget.channelWidget), ), ), @@ -591,13 +592,13 @@ class _ChannelListViewState extends State { Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: StreamChannel( + channel: channel, child: ChannelName( textStyle: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, ), ), - channel: channel, ), ), ], diff --git a/packages/stream_chat_flutter/lib/src/channel_media_display_screen.dart b/packages/stream_chat_flutter/lib/src/channel_media_display_screen.dart index 87ab2f3b9..251143edf 100644 --- a/packages/stream_chat_flutter/lib/src/channel_media_display_screen.dart +++ b/packages/stream_chat_flutter/lib/src/channel_media_display_screen.dart @@ -78,12 +78,12 @@ class _ChannelMediaDisplayScreenState extends State { Navigator.of(context).pop(); }, child: Container( + width: 24.0, + height: 24.0, child: StreamSvgIcon.left( color: StreamChatTheme.of(context).colorTheme.black, size: 24.0, ), - width: 24.0, - height: 24.0, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/channel_preview.dart b/packages/stream_chat_flutter/lib/src/channel_preview.dart index 2d29f12bb..9ba34f3a8 100644 --- a/packages/stream_chat_flutter/lib/src/channel_preview.dart +++ b/packages/stream_chat_flutter/lib/src/channel_preview.dart @@ -32,16 +32,37 @@ class ChannelPreview extends StatelessWidget { /// The function called when the image is tapped final VoidCallback onImageTap; + /// Widget rendering the title + final Widget title; + + /// Widget rendering the subtitle + final Widget subtitle; + + /// Widget rendering the leading element, by default it shows the [ChannelImage] + final Widget leading; + + /// Widget rendering the trailing element, by default it shows the last message date + final Widget trailing; + + /// Widget rendering the sending indicator, by default it uses the [SendingIndicator] widget + final Widget sendingIndicator; + ChannelPreview({ @required this.channel, Key key, this.onTap, this.onLongPress, this.onImageTap, + this.title, + this.subtitle, + this.leading, + this.sendingIndicator, + this.trailing, }) : super(key: key); @override Widget build(BuildContext context) { + final channelPreviewTheme = StreamChatTheme.of(context).channelPreviewTheme; return StreamBuilder( stream: channel.isMutedStream, initialData: channel.isMuted, @@ -49,6 +70,7 @@ class ChannelPreview extends StatelessWidget { return Opacity( opacity: snapshot.data ? 0.5 : 1, child: ListTile( + visualDensity: VisualDensity.compact, contentPadding: const EdgeInsets.symmetric( horizontal: 8, ), @@ -62,17 +84,18 @@ class ChannelPreview extends StatelessWidget { onLongPress(channel); } }, - leading: ChannelImage( - onTap: onImageTap, - ), + leading: leading ?? + ChannelImage( + onTap: onImageTap, + ), title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( - child: ChannelName( - textStyle: - StreamChatTheme.of(context).channelPreviewTheme.title, - ), + child: title ?? + ChannelName( + textStyle: channelPreviewTheme.title, + ), ), StreamBuilder>( stream: channel.state.membersStream, @@ -93,37 +116,36 @@ class ChannelPreview extends StatelessWidget { subtitle: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Flexible(child: _buildSubtitle(context)), - Builder( - builder: (context) { - final lastMessage = channel.state.messages.lastWhere( - (m) => !m.isDeleted && m.shadowed != true, - orElse: () => null, - ); - if (lastMessage?.user?.id == - StreamChat.of(context).user.id) { - return Padding( - padding: const EdgeInsets.only(right: 4.0), - child: SendingIndicator( - message: lastMessage, - size: StreamChatTheme.of(context) - .channelPreviewTheme - .indicatorIconSize, - isMessageRead: channel.state.read - ?.where((element) => - element.user.id != - channel.client.state.user.id) - ?.where((element) => element.lastRead - .isAfter(lastMessage.createdAt)) - ?.isNotEmpty == - true, - ), - ); - } - return SizedBox(); - }, - ), - _buildDate(context), + Flexible(child: subtitle ?? _buildSubtitle(context)), + sendingIndicator ?? + Builder( + builder: (context) { + final lastMessage = channel.state.messages.lastWhere( + (m) => !m.isDeleted && m.shadowed != true, + orElse: () => null, + ); + if (lastMessage?.user?.id == + StreamChat.of(context).user.id) { + return Padding( + padding: const EdgeInsets.only(right: 4.0), + child: SendingIndicator( + message: lastMessage, + size: channelPreviewTheme.indicatorIconSize, + isMessageRead: channel.state.read + ?.where((element) => + element.user.id != + channel.client.state.user.id) + ?.where((element) => element.lastRead + .isAfter(lastMessage.createdAt)) + ?.isNotEmpty == + true, + ), + ); + } + return SizedBox(); + }, + ), + trailing ?? _buildDate(context), ], ), ), @@ -176,15 +198,7 @@ class ChannelPreview extends StatelessWidget { ), Text( ' Channel is muted', - style: StreamChatTheme.of(context) - .channelPreviewTheme - .subtitle - .copyWith( - color: StreamChatTheme.of(context) - .channelPreviewTheme - .subtitle - .color, - ), + style: StreamChatTheme.of(context).channelPreviewTheme.subtitle, ), ], ); @@ -192,10 +206,7 @@ class ChannelPreview extends StatelessWidget { return TypingIndicator( channel: channel, alternativeWidget: _buildLastMessage(context), - style: StreamChatTheme.of(context).channelPreviewTheme.subtitle.copyWith( - color: - StreamChatTheme.of(context).channelPreviewTheme.subtitle.color, - ), + style: StreamChatTheme.of(context).channelPreviewTheme.subtitle, ); } diff --git a/packages/stream_chat_flutter/lib/src/extension.dart b/packages/stream_chat_flutter/lib/src/extension.dart index f19d851b3..65b1b1006 100644 --- a/packages/stream_chat_flutter/lib/src/extension.dart +++ b/packages/stream_chat_flutter/lib/src/extension.dart @@ -1,6 +1,7 @@ import 'package:characters/characters.dart'; import 'package:emojis/emoji.dart'; import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; final _emojis = Emoji.all(); @@ -44,3 +45,55 @@ extension PlatformFileX on PlatformFile { size: size, ); } + +extension InputDecorationX on InputDecoration { + InputDecoration merge(InputDecoration other) { + if (other == null) return this; + return copyWith( + icon: other?.icon, + labelText: other?.labelText, + labelStyle: labelStyle?.merge(other.labelStyle) ?? other.labelStyle, + helperText: other?.helperText, + helperStyle: helperStyle?.merge(other.helperStyle) ?? other.helperStyle, + helperMaxLines: other?.helperMaxLines, + hintText: other?.hintText, + hintStyle: hintStyle?.merge(other.hintStyle) ?? other.hintStyle, + hintTextDirection: other?.hintTextDirection, + hintMaxLines: other?.hintMaxLines, + errorText: other?.errorText, + errorStyle: errorStyle?.merge(other.errorStyle) ?? other.errorStyle, + errorMaxLines: other?.errorMaxLines, + floatingLabelBehavior: other?.floatingLabelBehavior, + isCollapsed: other?.isCollapsed, + isDense: other?.isDense, + contentPadding: other?.contentPadding, + prefixIcon: other?.prefixIcon, + prefix: other?.prefix, + prefixText: other?.prefixText, + prefixIconConstraints: other?.prefixIconConstraints, + prefixStyle: prefixStyle?.merge(other.prefixStyle) ?? other.prefixStyle, + suffixIcon: other?.suffixIcon, + suffix: other?.suffix, + suffixText: other?.suffixText, + suffixStyle: suffixStyle?.merge(other.suffixStyle) ?? other.suffixStyle, + suffixIconConstraints: other?.suffixIconConstraints, + counter: other?.counter, + counterText: other?.counterText, + counterStyle: + counterStyle?.merge(other.counterStyle) ?? other.counterStyle, + filled: other?.filled, + fillColor: other?.fillColor, + focusColor: other?.focusColor, + hoverColor: other?.hoverColor, + errorBorder: other?.errorBorder, + focusedBorder: other?.focusedBorder, + focusedErrorBorder: other?.focusedErrorBorder, + disabledBorder: other?.disabledBorder, + enabledBorder: other?.enabledBorder, + border: other?.border, + enabled: other?.enabled, + semanticCounterText: other?.semanticCounterText, + alignLabelWithHint: other?.alignLabelWithHint, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/full_screen_media.dart b/packages/stream_chat_flutter/lib/src/full_screen_media.dart index 6da6a2e06..88c20a517 100644 --- a/packages/stream_chat_flutter/lib/src/full_screen_media.dart +++ b/packages/stream_chat_flutter/lib/src/full_screen_media.dart @@ -243,7 +243,7 @@ class VideoPackage { ChewieController get chewieController => _chewieController; - bool get initialized => _videoPlayerController.value.initialized; + bool get initialized => _videoPlayerController.value.isInitialized; VideoPackage( Attachment attachment, { diff --git a/packages/stream_chat_flutter/lib/src/image_actions_modal.dart b/packages/stream_chat_flutter/lib/src/image_actions_modal.dart deleted file mode 100644 index 1304b90d8..000000000 --- a/packages/stream_chat_flutter/lib/src/image_actions_modal.dart +++ /dev/null @@ -1,192 +0,0 @@ -import 'dart:typed_data'; -import 'dart:ui'; - -import 'package:dio/dio.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:image_gallery_saver/image_gallery_saver.dart'; -import 'package:path_provider/path_provider.dart'; - -import '../stream_chat_flutter.dart'; -import 'extension.dart'; - -class ImageActionsModal extends StatelessWidget { - final Message message; - final String userName; - final String sentAt; - final List urls; - final currentIndex; - final VoidCallback onShowMessage; - - ImageActionsModal( - {this.message, - this.userName, - this.sentAt, - this.urls, - this.currentIndex, - this.onShowMessage}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => Navigator.maybePop(context), - child: _buildPage(context), - ); - } - - Widget _buildPage(context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - SizedBox(height: kToolbarHeight), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Container( - width: MediaQuery.of(context).size.width * 0.5, - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16.0), - ), - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: [ - _buildButton( - context, - 'Reply', - StreamSvgIcon.iconCurveLineLeftUp( - size: 24.0, - color: StreamChatTheme.of(context).colorTheme.grey, - ), - () { - Navigator.pop(context, ReturnActionType.reply); - }, - ), - _buildButton( - context, - 'Show in Chat', - StreamSvgIcon.eye( - size: 24.0, - color: StreamChatTheme.of(context).colorTheme.black, - ), - onShowMessage, - ), - _buildButton( - context, - 'Save ${urls[currentIndex].type == 'video' ? 'Video' : 'Image'}', - StreamSvgIcon.iconSave( - size: 24.0, - color: StreamChatTheme.of(context).colorTheme.grey, - ), - () async { - var url = urls[currentIndex].imageUrl ?? - urls[currentIndex].assetUrl ?? - urls[currentIndex].thumbUrl; - - Navigator.pop(context); - - if (urls[currentIndex].type == 'video') { - await _saveVideo(url); - } else { - await _saveImage(url); - } - }, - ), - if (StreamChat.of(context).user.id == message.user.id) - _buildButton( - context, - 'Delete', - StreamSvgIcon.delete( - size: 24.0, - color: StreamChatTheme.of(context).colorTheme.accentRed, - ), - () { - final channel = StreamChannel.of(context).channel; - if (message.attachments.length > 1 || - message.text.isNotEmpty) { - final remainingAttachments = [...message.attachments] - ..removeAt(currentIndex); - channel.updateMessage(message.copyWith( - attachments: remainingAttachments, - )); - Navigator.pop(context); - Navigator.pop(context); - } else { - channel.deleteMessage(message).then((value) { - Navigator.pop(context); - Navigator.pop(context); - }); - } - }, - color: StreamChatTheme.of(context).colorTheme.accentRed, - ), - ] - .map((e) => - Align(alignment: Alignment.centerRight, child: e)) - .insertBetween( - Container( - height: 1, - color: - StreamChatTheme.of(context).colorTheme.greyWhisper, - ), - ), - ), - ), - ), - ) - ], - ); - } - - Widget _buildButton( - context, - String title, - StreamSvgIcon icon, - VoidCallback onTap, { - Color color, - }) { - return Material( - color: StreamChatTheme.of(context).colorTheme.white, - child: InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), - child: Row( - children: [ - icon, - SizedBox(width: 16), - Text( - title, - style: StreamChatTheme.of(context) - .textTheme - .body - .copyWith(color: color), - ), - ], - ), - ), - ), - ); - } - - Future _saveImage(String url) async { - var response = await Dio() - .get(url, options: Options(responseType: ResponseType.bytes)); - final result = await ImageGallerySaver.saveImage( - Uint8List.fromList(response.data), - quality: 60, - name: '${DateTime.now().millisecondsSinceEpoch}'); - return result; - } - - Future _saveVideo(String url) async { - var appDocDir = await getTemporaryDirectory(); - var savePath = - appDocDir.path + '/${DateTime.now().millisecondsSinceEpoch}.mp4'; - await Dio().download(url, savePath); - final result = await ImageGallerySaver.saveFile(savePath); - print(result); - } -} diff --git a/packages/stream_chat_flutter/lib/src/image_footer.dart b/packages/stream_chat_flutter/lib/src/image_footer.dart index 7140e490e..1d0d7e78b 100644 --- a/packages/stream_chat_flutter/lib/src/image_footer.dart +++ b/packages/stream_chat_flutter/lib/src/image_footer.dart @@ -3,9 +3,10 @@ import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:dio/dio.dart'; -import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/video_thumbnail_image.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -90,27 +91,40 @@ class _ImageFooterState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - IconButton( - icon: StreamSvgIcon.iconShare( - size: 24.0, - color: StreamChatTheme.of(context).colorTheme.black, - ), - onPressed: () async { - final attachment = - widget.mediaAttachments[widget.currentPage]; - var url = attachment.imageUrl ?? - attachment.assetUrl ?? - attachment.thumbUrl; - var type = attachment.type == 'image' - ? 'jpg' - : url?.split('?')?.first?.split('.')?.last ?? 'jpg'; - var request = await HttpClient().getUrl(Uri.parse(url)); - var response = await request.close(); - var bytes = - await consolidateHttpClientResponseBytes(response); - await Share.file('File', 'image.$type', bytes, 'image/$type'); - }, - ), + kIsWeb + ? SizedBox() + : IconButton( + icon: StreamSvgIcon.iconShare( + size: 24.0, + color: StreamChatTheme.of(context).colorTheme.black, + ), + onPressed: () async { + final attachment = + widget.mediaAttachments[widget.currentPage]; + final url = attachment.imageUrl ?? + attachment.assetUrl ?? + attachment.thumbUrl; + final type = attachment.type == 'image' + ? 'jpg' + : url?.split('?')?.first?.split('.')?.last ?? 'jpg'; + final request = + await HttpClient().getUrl(Uri.parse(url)); + final response = await request.close(); + final bytes = + await consolidateHttpClientResponseBytes(response); + final tmpPath = await getTemporaryDirectory(); + final filePath = + '${tmpPath.path}/${attachment.id}.$type'; + final file = File(filePath); + await file.writeAsBytes(bytes); + await Share.shareFiles( + [filePath], + mimeTypes: [ + 'image/$type', + ], + ); + }, + ), InkWell( onTap: widget.onTitleTap, child: Container( @@ -223,13 +237,13 @@ class _ImageFooterState extends State { media = InkWell( onTap: () => widget.mediaSelectedCallBack(index), child: AspectRatio( + aspectRatio: 1.0, child: CachedNetworkImage( imageUrl: attachment.imageUrl ?? attachment.assetUrl ?? attachment.thumbUrl, fit: BoxFit.cover, ), - aspectRatio: 1.0, ), ); } diff --git a/packages/stream_chat_flutter/lib/src/image_header.dart b/packages/stream_chat_flutter/lib/src/image_header.dart index 25eab839a..bf4ec474d 100644 --- a/packages/stream_chat_flutter/lib/src/image_header.dart +++ b/packages/stream_chat_flutter/lib/src/image_header.dart @@ -3,7 +3,7 @@ import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; -import 'image_actions_modal.dart'; +import 'attachment_actions_modal.dart'; class ImageHeader extends StatelessWidget implements PreferredSizeWidget { /// True if this header shows the leading back button @@ -110,11 +110,8 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget { builder: (context) { return StreamChannel( channel: channel, - child: ImageActionsModal( - userName: userName, - sentAt: sentAt, + child: AttachmentActionsModal( message: message, - urls: urls, currentIndex: currentIndex, onShowMessage: onShowMessage, ), diff --git a/packages/stream_chat_flutter/lib/src/media_list_view.dart b/packages/stream_chat_flutter/lib/src/media_list_view.dart index 7550e3e47..ddaf2c24a 100644 --- a/packages/stream_chat_flutter/lib/src/media_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/media_list_view.dart @@ -56,6 +56,11 @@ class _MediaListViewState extends State { return Padding( padding: const EdgeInsets.symmetric(horizontal: 1.0, vertical: 1.0), child: InkWell( + onTap: () { + if (widget.onSelect != null) { + widget.onSelect(media); + } + }, child: Stack( children: [ AspectRatio( @@ -125,11 +130,6 @@ class _MediaListViewState extends State { ] ], ), - onTap: () { - if (widget.onSelect != null) { - widget.onSelect(media); - } - }, ), ); }, diff --git a/packages/stream_chat_flutter/lib/src/message_action.dart b/packages/stream_chat_flutter/lib/src/message_action.dart new file mode 100644 index 000000000..5cedc962a --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_action.dart @@ -0,0 +1,21 @@ +import 'package:flutter/widgets.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// Class describing a message action +class MessageAction { + /// leading widget + final Widget leading; + + /// title widget + final Widget title; + + /// callback called on tap + final OnMessageTap onTap; + + /// returns a new instance of a [MessageAction] + MessageAction({ + this.leading, + this.title, + this.onTap, + }); +} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal.dart index 1546e66b9..883210bad 100644 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_actions_modal.dart @@ -4,6 +4,7 @@ import 'dart:ui'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:stream_chat_flutter/src/message_action.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/src/reaction_picker.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; @@ -34,6 +35,9 @@ class MessageActionsModal extends StatefulWidget { final ShapeBorder attachmentShape; final DisplayWidget showUserAvatar; + /// List of custom actions + final List customActions; + const MessageActionsModal({ Key key, @required this.message, @@ -53,6 +57,7 @@ class MessageActionsModal extends StatefulWidget { this.messageShape, this.attachmentShape, this.reverse = false, + this.customActions = const [], }) : super(key: key); @override @@ -223,6 +228,12 @@ class _MessageActionsModalState extends State { _buildFlagButton(context), if (widget.showDeleteMessage) _buildDeleteButton(context), + ...widget.customActions.map((action) { + return _buildCustomAction( + context, + action, + ); + }) ].insertBetween( Container( height: 1, @@ -248,27 +259,69 @@ class _MessageActionsModalState extends State { ); } + InkWell _buildCustomAction( + BuildContext context, + MessageAction messageAction, + ) { + return InkWell( + onTap: () { + messageAction.onTap?.call(widget.message); + }, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0), + child: Row( + children: [ + messageAction.leading ?? Offstage(), + const SizedBox(width: 16), + messageAction.title ?? Offstage(), + ], + ), + ), + ); + } + void _showFlagDialog() async { final client = StreamChat.of(context).client; - var answer = await showConfirmationDialog(context, - title: 'Flag Message', - icon: StreamSvgIcon.flag( - color: StreamChatTheme.of(context).colorTheme.accentRed, - size: 24.0, - ), - question: - 'Do you want to send a copy of this message to a\nmoderator for further investigation?', - okText: 'FLAG', - cancelText: 'CANCEL'); + final answer = await showConfirmationDialog( + context, + title: 'Flag Message', + icon: StreamSvgIcon.flag( + color: StreamChatTheme.of(context).colorTheme.accentRed, + size: 24.0, + ), + question: + 'Do you want to send a copy of this message to a\nmoderator for further investigation?', + okText: 'FLAG', + cancelText: 'CANCEL', + ); - if (answer) { + final theme = StreamChatTheme.of(context); + if (answer == true) { try { await client.flagMessage(widget.message.id); - _showDismissAlert(); + await showInfoDialog( + context, + icon: StreamSvgIcon.flag( + color: theme.colorTheme.accentRed, + size: 24.0, + ), + details: 'The message has been reported to a moderator.', + title: 'Message flagged', + okText: 'OK', + ); } catch (err) { if (json.decode(err?.body ?? {})['code'] == 4) { - _showDismissAlert(); + await showInfoDialog( + context, + icon: StreamSvgIcon.flag( + color: theme.colorTheme.accentRed, + size: 24.0, + ), + details: 'The message has been reported to a moderator.', + title: 'Message flagged', + okText: 'OK', + ); } else { _showErrorAlert(); } @@ -306,133 +359,16 @@ class _MessageActionsModalState extends State { } } - void _showDismissAlert() { - showModalBottomSheet( - backgroundColor: StreamChatTheme.of(context).colorTheme.white, - context: context, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0), - topRight: Radius.circular(16.0), - )), - builder: (context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - height: 26.0, - ), - StreamSvgIcon.flag( - color: StreamChatTheme.of(context).colorTheme.accentRed, - size: 24.0, - ), - SizedBox( - height: 26.0, - ), - Text( - 'Message flagged', - style: StreamChatTheme.of(context).textTheme.headlineBold, - ), - SizedBox( - height: 7.0, - ), - Text('The message has been reported to a moderator.'), - SizedBox( - height: 36.0, - ), - Container( - color: - StreamChatTheme.of(context).colorTheme.black.withOpacity(.08), - height: 1.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - TextButton( - child: Text( - 'OK', - style: StreamChatTheme.of(context) - .textTheme - .bodyBold - .copyWith( - color: StreamChatTheme.of(context) - .colorTheme - .accentBlue), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ), - ], - ); - }, - ); - } - void _showErrorAlert() { - showModalBottomSheet( - backgroundColor: StreamChatTheme.of(context).colorTheme.white, - context: context, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0), - topRight: Radius.circular(16.0), - )), - builder: (context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - height: 26.0, - ), - StreamSvgIcon.error( - color: StreamChatTheme.of(context).colorTheme.accentRed, - size: 24.0, - ), - SizedBox( - height: 26.0, - ), - Text( - 'Something went wrong', - style: StreamChatTheme.of(context).textTheme.headlineBold, - ), - SizedBox( - height: 7.0, - ), - Text('The operation couldn\'t be completed.'), - SizedBox( - height: 36.0, - ), - Container( - color: - StreamChatTheme.of(context).colorTheme.black.withOpacity(.08), - height: 1.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - TextButton( - child: Text( - 'OK', - style: StreamChatTheme.of(context) - .textTheme - .bodyBold - .copyWith( - color: StreamChatTheme.of(context) - .colorTheme - .accentBlue), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ), - ], - ); - }, + showInfoDialog( + context, + icon: StreamSvgIcon.error( + color: StreamChatTheme.of(context).colorTheme.accentRed, + size: 24.0, + ), + details: 'The operation couldn\'t be completed.', + title: 'Something went wrong', + okText: 'OK', ); } @@ -637,21 +573,16 @@ class _MessageActionsModalState extends State { ], ), ), - Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).viewInsets.bottom, - ), - child: widget.editMessageInputBuilder != null - ? widget.editMessageInputBuilder(context, widget.message) - : MessageInput( - editMessage: widget.message, - preMessageSending: (m) { - FocusScope.of(context).unfocus(); - Navigator.pop(context); - return m; - }, - ), - ), + widget.editMessageInputBuilder != null + ? widget.editMessageInputBuilder(context, widget.message) + : MessageInput( + editMessage: widget.message, + preMessageSending: (m) { + FocusScope.of(context).unfocus(); + Navigator.pop(context); + return m; + }, + ), ], ), ); diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 21424c2e6..21dda0f4e 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -11,6 +11,7 @@ import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:image_picker/image_picker.dart'; import 'package:photo_manager/photo_manager.dart'; +import 'package:shimmer/shimmer.dart'; import 'package:stream_chat_flutter/src/video_service.dart'; import 'package:stream_chat_flutter/src/media_list_view.dart'; import 'package:stream_chat_flutter/src/message_list_view.dart'; @@ -42,6 +43,15 @@ enum DefaultAttachmentTypes { file, } +/// Available locations for the sendMessage button relative to the textField +enum SendButtonLocation { + /// inside the textField + inside, + + /// outside the textField + outside, +} + const _kMinMediaPickerSize = 360.0; const _kMaxAttachmentSize = 20971520; // 20MB in Bytes @@ -107,6 +117,11 @@ class MessageInput extends StatefulWidget { this.focusNode, this.quotedMessage, this.onQuotedMessageCleared, + this.sendButtonLocation = SendButtonLocation.outside, + this.autofocus = false, + this.hideSendAsDm = false, + this.idleSendButton, + this.activeSendButton, }) : super(key: key); /// Message to edit @@ -134,6 +149,9 @@ class MessageInput extends StatefulWidget { /// If true the attachments button will not be displayed final bool disableAttachments; + /// Hide send as dm checkbox + final bool hideSendAsDm; + /// The text controller of the TextField final TextEditingController textEditingController; @@ -155,6 +173,18 @@ class MessageInput extends StatefulWidget { /// final VoidCallback onQuotedMessageCleared; + /// The location of the send button + final SendButtonLocation sendButtonLocation; + + /// Autofocus property passed to the TextField + final bool autofocus; + + /// Send button widget in an idle state + final Widget idleSendButton; + + /// Send button widget in an active state + final Widget activeSendButton; + @override MessageInputState createState() => MessageInputState(); @@ -281,7 +311,7 @@ class MessageInputState extends State { padding: const EdgeInsets.all(8.0), child: _buildTextField(context), ), - if (widget.parentMessage != null) + if (widget.parentMessage != null && !widget.hideSendAsDm) Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: _buildDmCheckbox(), @@ -304,15 +334,16 @@ class MessageInputState extends State { Flex _buildTextField(BuildContext context) { return Flex( direction: Axis.horizontal, - crossAxisAlignment: CrossAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, children: [ if (!_commandEnabled) _buildExpandActionsButton(), if (widget.actionsLocation == ActionsLocation.left) ...widget.actions ?? [], _buildTextInput(context), - _animateSendButton(context), if (widget.actionsLocation == ActionsLocation.right) ...widget.actions ?? [], + if (widget.sendButtonLocation == SendButtonLocation.outside) + _animateSendButton(context), ], ); } @@ -384,14 +415,20 @@ class MessageInputState extends State { } Widget _animateSendButton(BuildContext context) { + final sendButton = widget.activeSendButton != null + ? InkWell( + onTap: sendMessage, + child: widget.activeSendButton, + ) + : _buildSendButton(context); return Padding( padding: const EdgeInsets.all(8.0), child: AnimatedCrossFade( crossFadeState: (_messageIsPresent || _attachments.isNotEmpty) ? CrossFadeState.showFirst : CrossFadeState.showSecond, - firstChild: _buildSendButton(context), - secondChild: _buildIdleSendButton(context), + firstChild: sendButton, + secondChild: widget.idleSendButton ?? _buildIdleSendButton(context), duration: StreamChatTheme.of(context).messageInputTheme.sendAnimationDuration, alignment: Alignment.center, @@ -447,101 +484,139 @@ class MessageInputState extends State { child: Container( clipBehavior: Clip.antiAlias, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20.0), - border: Border.all(color: theme.colorTheme.greyGainsboro), + borderRadius: theme.messageInputTheme.borderRadius, + gradient: _focusNode.hasFocus + ? theme.messageInputTheme.activeBorderGradient + : theme.messageInputTheme.idleBorderGradient, ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildReplyToMessage(), - _buildAttachments(), - LimitedBox( - maxHeight: widget.maxHeight, - child: TextField( - key: Key('messageInputText'), - enabled: _inputEnabled, - minLines: null, - maxLines: null, - onSubmitted: (_) => sendMessage(), - keyboardType: widget.keyboardType, - controller: textEditingController, - focusNode: _focusNode, - style: theme.textTheme.body, - autofocus: false, - textAlignVertical: TextAlignVertical.center, - decoration: InputDecoration( - isDense: true, - hintText: _getHint(), - hintStyle: theme.textTheme.body.copyWith( - color: theme.colorTheme.grey, + child: Padding( + padding: const EdgeInsets.all(1.5), + child: Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: theme.messageInputTheme.borderRadius, + color: theme.messageInputTheme.inputBackground, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildReplyToMessage(), + _buildAttachments(), + LimitedBox( + maxHeight: widget.maxHeight, + child: TextField( + key: Key('messageInputText'), + enabled: _inputEnabled, + minLines: null, + maxLines: null, + onSubmitted: (_) => sendMessage(), + keyboardType: widget.keyboardType, + controller: textEditingController, + focusNode: _focusNode, + style: theme.messageInputTheme.inputTextStyle, + autofocus: widget.autofocus, + textAlignVertical: TextAlignVertical.center, + decoration: _getInputDecoration(), + textCapitalization: TextCapitalization.sentences, ), - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.transparent)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.transparent)), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.transparent)), - errorBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.transparent)), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.transparent)), - contentPadding: const EdgeInsets.fromLTRB(16, 12, 13, 11), - prefixIconConstraints: BoxConstraints.tight(Size(78, 24)), - suffixIconConstraints: BoxConstraints.tight(Size(40, 40)), - prefixIcon: _commandEnabled - ? Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: theme.colorTheme.accentBlue, - ), - margin: const EdgeInsets.only(right: 4, left: 8), - alignment: Alignment.center, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - StreamSvgIcon.lightning( - color: Colors.white, - size: 16.0, - ), - Text( - _chosenCommand?.name?.toUpperCase() ?? '', - style: StreamChatTheme.of(context) - .textTheme - .footnoteBold - .copyWith( - color: Colors.white, - ), - ), - ], - ), - ) - : null, - suffixIcon: _commandEnabled - ? IconButton( - icon: StreamSvgIcon.closeSmall(), - splashRadius: 24, - padding: const EdgeInsets.all(0), - constraints: BoxConstraints.tightFor( - height: 24, - width: 24, - ), - onPressed: () { - setState(() => _commandEnabled = false); - }, - ) - : null, - ), - textCapitalization: TextCapitalization.sentences, - ), - ) - ], + ) + ], + ), + ), ), ), ), ); } + InputDecoration _getInputDecoration() { + final theme = StreamChatTheme.of(context); + final passedDecoration = theme.messageInputTheme.inputDecoration; + return InputDecoration( + isDense: true, + hintText: _getHint(), + hintStyle: theme.messageInputTheme.inputTextStyle.copyWith( + color: theme.colorTheme.grey, + ), + border: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.transparent, + ), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.transparent, + ), + ), + disabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.transparent, + ), + ), + contentPadding: const EdgeInsets.fromLTRB(16, 12, 13, 11), + prefixIconConstraints: BoxConstraints.tight(Size(78, 24)), + suffixIconConstraints: BoxConstraints.tight(Size(40, 40)), + prefixIcon: _commandEnabled + ? Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: theme.colorTheme.accentBlue, + ), + margin: const EdgeInsets.only(right: 4, left: 8), + alignment: Alignment.center, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + StreamSvgIcon.lightning( + color: Colors.white, + size: 16.0, + ), + Text( + _chosenCommand?.name?.toUpperCase() ?? '', + style: StreamChatTheme.of(context) + .textTheme + .footnoteBold + .copyWith( + color: Colors.white, + ), + ), + ], + ), + ) + : null, + suffixIcon: Row( + children: [ + if (_commandEnabled) + IconButton( + icon: StreamSvgIcon.closeSmall(), + splashRadius: 24, + padding: const EdgeInsets.all(0), + constraints: BoxConstraints.tightFor( + height: 24, + width: 24, + ), + onPressed: () { + setState(() => _commandEnabled = false); + }, + ), + if (widget.sendButtonLocation == SendButtonLocation.inside) + _animateSendButton(context), + ], + ), + ).merge(passedDecoration); + } + Timer _debounce; void _onChanged(BuildContext context, String s) { @@ -621,7 +696,9 @@ class MessageInputState extends State { .last .contains('@')) { _mentionsOverlay = _buildMentionsOverlayEntry(); - Overlay.of(context).insert(_mentionsOverlay); + if (_mentionsOverlay != null) { + Overlay.of(context).insert(_mentionsOverlay); + } } } @@ -646,7 +723,9 @@ class MessageInputState extends State { _commandsOverlay = null; } else { _commandsOverlay = _buildCommandsOverlayEntry(); - Overlay.of(context).insert(_commandsOverlay); + if (_commandsOverlay != null) { + Overlay.of(context).insert(_commandsOverlay); + } } } } @@ -661,6 +740,10 @@ class MessageInputState extends State { ?.toList() ?? []; + if (commands.isEmpty) { + return null; + } + RenderBox renderBox = context.findRenderObject(); final size = renderBox.size; @@ -833,6 +916,7 @@ class MessageInputState extends State { child: Material( color: StreamChatTheme.of(context).colorTheme.whiteSmoke, child: Column( + mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, @@ -930,7 +1014,19 @@ class MessageInputState extends State { color: StreamChatTheme.of(context).colorTheme.white, borderRadius: BorderRadius.circular(8.0), ), - child: _buildPickerSection(), + child: _PickerWidget( + filePickerIndex: _filePickerIndex, + containsFile: _attachmentContainsFile, + selectedMedias: _attachments.keys.toList(), + onAddMoreFilesClick: pickFile, + onMediaSelected: (media) { + if (_attachments.containsKey(media.id)) { + setState(() => _attachments.remove(media.id)); + } else { + _addAttachment(media); + } + }, + ), ), ), ], @@ -939,109 +1035,6 @@ class MessageInputState extends State { ); } - Widget _buildPickerSection() { - final _attachmentContainsFile = _attachments.values.any((it) { - return it.type == 'file'; - }); - - switch (_filePickerIndex) { - case 0: - return FutureBuilder( - future: PhotoManager.requestPermission(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return Center( - child: CircularProgressIndicator(), - ); - } - - if (snapshot.data) { - if (_attachmentContainsFile) { - return GestureDetector( - onTap: () { - pickFile(DefaultAttachmentTypes.file); - }, - child: Container( - constraints: BoxConstraints.expand(), - color: StreamChatTheme.of(context).colorTheme.whiteSmoke, - child: Text( - 'Add more files', - style: TextStyle( - color: - StreamChatTheme.of(context).colorTheme.accentBlue, - fontWeight: FontWeight.bold, - ), - ), - alignment: Alignment.center, - ), - ); - } - return MediaListView( - selectedIds: _attachments.keys.toList(), - onSelect: (media) async { - if (!_attachments.containsKey(media.id)) { - _addAttachment(media); - } else { - setState(() => _attachments.remove(media.id)); - } - }, - ); - } - - return InkWell( - onTap: () async { - PhotoManager.openSetting(); - }, - child: Container( - color: StreamChatTheme.of(context).colorTheme.whiteSmoke, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - SvgPicture.asset( - 'svgs/icon_picture_empty_state.svg', - package: 'stream_chat_flutter', - height: 140, - color: StreamChatTheme.of(context) - .colorTheme - .greyGainsboro, - ), - Text( - 'Please enable access to your photos \nand videos so you can share them with friends.', - style: StreamChatTheme.of(context) - .textTheme - .body - .copyWith( - color: StreamChatTheme.of(context) - .colorTheme - .grey), - textAlign: TextAlign.center, - ), - SizedBox(height: 6.0), - Center( - child: Text( - 'Allow access to your gallery', - style: StreamChatTheme.of(context) - .textTheme - .bodyBold - .copyWith( - color: StreamChatTheme.of(context) - .colorTheme - .accentBlue, - ), - ), - ), - ], - ), - ), - ); - }); - break; - default: - return SizedBox(); - } - } - void _addAttachment(AssetEntity medium) async { final mediaFile = await medium.originFile.timeout( Duration(seconds: 5), @@ -1090,81 +1083,81 @@ class MessageInputState extends State { switch (iconType) { case 'giphy': return CircleAvatar( + radius: 12, child: StreamSvgIcon.giphyIcon( size: 24.0, ), - radius: 12, ); break; case 'ban': return CircleAvatar( backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue, + radius: 12, child: StreamSvgIcon.iconUserDelete( size: 16.0, color: Colors.white, ), - radius: 12, ); break; case 'flag': return CircleAvatar( backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue, + radius: 12, child: StreamSvgIcon.flag( size: 14.0, color: Colors.white, ), - radius: 12, ); break; case 'imgur': return CircleAvatar( backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue, + radius: 12, child: ClipOval( child: StreamSvgIcon.imgur( size: 24.0, ), ), - radius: 12, ); break; case 'mute': return CircleAvatar( backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue, + radius: 12, child: StreamSvgIcon.mute( size: 16.0, color: Colors.white, ), - radius: 12, ); break; case 'unban': return CircleAvatar( backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue, + radius: 12, child: StreamSvgIcon.userAdd( size: 16.0, color: Colors.white, ), - radius: 12, ); break; case 'unmute': return CircleAvatar( backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue, + radius: 12, child: StreamSvgIcon.volumeUp( size: 16.0, color: Colors.white, ), - radius: 12, ); break; default: return CircleAvatar( backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue, + radius: 12, child: StreamSvgIcon.lightning( size: 16.0, color: Colors.white, ), - radius: 12, ); break; } @@ -1191,6 +1184,10 @@ class MessageInputState extends State { })?.toList() ?? []; + if (members.isEmpty) { + return null; + } + RenderBox renderBox = context.findRenderObject(); final size = renderBox.size; @@ -1646,11 +1643,15 @@ class MessageInputState extends State { return getFileTypeImage(attachment.extraData['other']); }, progressIndicatorBuilder: (context, _, progress) { - return Center( - child: Container( - width: 20.0, - height: 20.0, - child: const CircularProgressIndicator(), + return Shimmer.fromColors( + baseColor: + StreamChatTheme.of(context).colorTheme.greyGainsboro, + highlightColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, + child: Image.asset( + 'images/placeholder.png', + fit: BoxFit.cover, + package: 'stream_chat_flutter', ), ); }, @@ -1676,8 +1677,8 @@ class MessageInputState extends State { ); default: return Container( - child: Icon(Icons.insert_drive_file), color: Colors.black26, + child: Icon(Icons.insert_drive_file), ); } } @@ -1903,14 +1904,12 @@ class MessageInputState extends State { if (file == null) return; - final mimeType = file.path.split('/').last.mimeType; + final mimeType = file.name?.mimeType; final extraDataMap = {}; - if (camera) { - if (mimeType.type == 'video' || mimeType.type == 'image') { - attachmentType = mimeType.type; - } + if (mimeType.type == 'video' || mimeType.type == 'image') { + attachmentType = mimeType.type; } else { attachmentType = 'file'; } @@ -2013,9 +2012,10 @@ class MessageInputState extends State { return; } + final shouldUnfocus = _commandEnabled; + if (_commandEnabled) { text = '/${_chosenCommand.name} ' + text; - FocusScope.of(context).unfocus(); } final attachments = [..._attachments.values]; @@ -2082,7 +2082,14 @@ class MessageInputState extends State { sendingFuture = channel.updateMessage(message); } + if (!shouldUnfocus) { + FocusScope.of(context).requestFocus(_focusNode); + } + return sendingFuture.then((resp) { + if (resp.message?.type == 'error') { + _parseExistingMessage(message); + } if (widget.onMessageSent != null) { widget.onMessageSent(resp.message); } @@ -2140,6 +2147,9 @@ class MessageInputState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, child: Text( 'OK', style: StreamChatTheme.of(context) @@ -2150,9 +2160,6 @@ class MessageInputState extends State { .colorTheme .accentBlue), ), - onPressed: () { - Navigator.of(context).pop(); - }, ), ], ), @@ -2240,3 +2247,114 @@ class Tuple2 { @override int get hashCode => item1.hashCode ^ item2.hashCode; } + +class _PickerWidget extends StatefulWidget { + final int filePickerIndex; + final bool containsFile; + final List selectedMedias; + final void Function(DefaultAttachmentTypes) onAddMoreFilesClick; + final void Function(AssetEntity) onMediaSelected; + + const _PickerWidget({ + Key key, + @required this.filePickerIndex, + @required this.containsFile, + @required this.selectedMedias, + @required this.onAddMoreFilesClick, + @required this.onMediaSelected, + }) : super(key: key); + + @override + __PickerWidgetState createState() => __PickerWidgetState(); +} + +class __PickerWidgetState extends State<_PickerWidget> { + Future requestPermission; + + @override + void initState() { + super.initState(); + requestPermission = PhotoManager.requestPermission(); + } + + @override + Widget build(BuildContext context) { + if (widget.filePickerIndex != 0) { + return Offstage(); + } + return FutureBuilder( + future: requestPermission, + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } + + if (snapshot.data) { + if (widget.containsFile) { + return GestureDetector( + onTap: () { + widget.onAddMoreFilesClick(DefaultAttachmentTypes.file); + }, + child: Container( + constraints: BoxConstraints.expand(), + color: StreamChatTheme.of(context).colorTheme.whiteSmoke, + alignment: Alignment.center, + child: Text( + 'Add more files', + style: TextStyle( + color: StreamChatTheme.of(context).colorTheme.accentBlue, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } + return MediaListView( + selectedIds: widget.selectedMedias, + onSelect: widget.onMediaSelected, + ); + } + + return InkWell( + onTap: () async { + PhotoManager.openSetting(); + }, + child: Container( + color: StreamChatTheme.of(context).colorTheme.whiteSmoke, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + SvgPicture.asset( + 'svgs/icon_picture_empty_state.svg', + package: 'stream_chat_flutter', + height: 140, + color: StreamChatTheme.of(context).colorTheme.greyGainsboro, + ), + Text( + 'Please enable access to your photos \nand videos so you can share them with friends.', + style: StreamChatTheme.of(context).textTheme.body.copyWith( + color: StreamChatTheme.of(context).colorTheme.grey), + textAlign: TextAlign.center, + ), + SizedBox(height: 6.0), + Center( + child: Text( + 'Allow access to your gallery', + style: StreamChatTheme.of(context) + .textTheme + .bodyBold + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .accentBlue, + ), + ), + ), + ], + ), + ), + ); + }); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view.dart index 505c4e0fa..e6c1e93b0 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view.dart @@ -28,10 +28,15 @@ typedef ParentMessageBuilder = Widget Function( BuildContext, Message, ); +typedef SystemMessageBuilder = Widget Function( + BuildContext, + Message, +); typedef ThreadBuilder = Widget Function(BuildContext context, Message parent); typedef ThreadTapCallback = void Function(Message, Widget); typedef OnMessageSwiped = void Function(Message); +typedef OnMessageTap = void Function(Message); typedef ReplyTapCallback = void Function(Message); class MessageDetails { @@ -128,14 +133,22 @@ class MessageListView extends StatefulWidget { this.showConnectionStateTile = false, this.loadingBuilder, this.emptyBuilder, + this.systemMessageBuilder, this.messageListBuilder, this.errorWidgetBuilder, + this.messageFilter, this.customAttachmentBuilders, + this.onMessageTap, + this.onSystemMessageTap, + this.onAttachmentTap, }) : super(key: key); /// Function used to build a custom message widget final MessageBuilder messageBuilder; + /// Function used to build a custom system message widget + final SystemMessageBuilder systemMessageBuilder; + /// Function used to build a custom parent message widget final ParentMessageBuilder parentMessageBuilder; @@ -204,10 +217,22 @@ class MessageListView extends StatefulWidget { /// of a connection failure. final ErrorBuilder errorWidgetBuilder; + /// Predicate used to filter messages + final bool Function(Message) messageFilter; + /// Attachment builders for the default message widget /// Please change this in the [MessageWidget] if you are using a custom implementation final Map customAttachmentBuilders; + /// Called when any message is tapped except a system message (use [onSystemMessageTap] instead) + final OnMessageTap onMessageTap; + + /// Called when system message is tapped + final OnMessageTap onSystemMessageTap; + + // Customize onTap on attachment + final void Function(Message message, Attachment attachment) onAttachmentTap; + @override _MessageListViewState createState() => _MessageListViewState(); } @@ -265,6 +290,7 @@ class _MessageListViewState extends State { @override Widget build(BuildContext context) { return MessageListCore( + messageFilter: widget.messageFilter, loadingBuilder: widget.loadingBuilder ?? (context) { return Center( @@ -356,6 +382,9 @@ class _MessageListViewState extends State { childAnchor: Alignment.topCenter, message: statusString, child: LazyLoadScrollView( + onPageScrollStart: () { + FocusScope.of(context).unfocus(); + }, onStartOfPage: () async { _inBetweenList = false; if (!_upToDate) { @@ -408,7 +437,7 @@ class _MessageListViewState extends State { style: StreamChatTheme.of(context) .channelTheme .channelHeaderTheme - .lastMessageAt, + .subtitle, ), ), ); @@ -595,9 +624,6 @@ class _MessageListViewState extends State { children: [ FloatingActionButton( backgroundColor: StreamChatTheme.of(context).colorTheme.white, - child: StreamSvgIcon.down( - color: StreamChatTheme.of(context).colorTheme.black, - ), onPressed: () { if (unreadCount > 0) { streamChannel.channel.markRead(); @@ -615,6 +641,9 @@ class _MessageListViewState extends State { ); } }, + child: StreamSvgIcon.down( + color: StreamChatTheme.of(context).colorTheme.black, + ), ), if (showUnreadCount) Positioned( @@ -804,6 +833,12 @@ class _MessageListViewState extends State { } }, customAttachmentBuilders: widget.customAttachmentBuilders, + onMessageTap: (message) { + if (widget.onMessageTap != null) { + widget.onMessageTap(message); + } + FocusScope.of(context).unfocus(); + }, ); } @@ -812,11 +847,19 @@ class _MessageListViewState extends State { List messages, int index, ) { - if (message.type == 'system' && message.text?.isNotEmpty == true) { - return SystemMessage( - key: ValueKey('MESSAGE-${message.id}'), - message: message, - ); + if ((message.type == 'system' || message.type == 'error') && + message.text?.isNotEmpty == true) { + return widget.systemMessageBuilder?.call(context, message) ?? + SystemMessage( + key: ValueKey('MESSAGE-${message.id}'), + message: message, + onMessageTap: (message) { + if (widget.onSystemMessageTap != null) { + widget.onSystemMessageTap(message); + } + FocusScope.of(context).unfocus(); + }, + ); } final userId = StreamChat.of(context).user.id; @@ -965,6 +1008,13 @@ class _MessageListViewState extends State { } }, customAttachmentBuilders: widget.customAttachmentBuilders, + onMessageTap: (message) { + if (widget.onMessageTap != null) { + widget.onMessageTap(message); + } + FocusScope.of(context).unfocus(); + }, + onAttachmentTap: widget.onAttachmentTap, ); if (!message.isDeleted && @@ -995,10 +1045,6 @@ class _MessageListViewState extends State { end: colorTheme.white.withOpacity(0), ), duration: const Duration(seconds: 3), - child: Padding( - padding: const EdgeInsets.only(top: 4.0), - child: child, - ), onEnd: () => initialMessageHighlightComplete = true, builder: (_, color, child) { return Container( @@ -1006,6 +1052,10 @@ class _MessageListViewState extends State { child: child, ); }, + child: Padding( + padding: const EdgeInsets.only(top: 4.0), + child: child, + ), ); } return child; diff --git a/packages/stream_chat_flutter/lib/src/message_reactions_modal.dart b/packages/stream_chat_flutter/lib/src/message_reactions_modal.dart index cc587786d..1d8dbae76 100644 --- a/packages/stream_chat_flutter/lib/src/message_reactions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_reactions_modal.dart @@ -237,6 +237,9 @@ class MessageReactionsModal extends StatelessWidget { borderRadius: BorderRadius.circular(32), ), Positioned( + bottom: 6, + left: isCurrentUser ? -3 : null, + right: isCurrentUser ? -3 : null, child: Align( alignment: reverse ? Alignment.centerRight : Alignment.centerLeft, @@ -250,9 +253,6 @@ class MessageReactionsModal extends StatelessWidget { highlightOwnReactions: false, ), ), - bottom: 6, - left: isCurrentUser ? -3 : null, - right: isCurrentUser ? -3 : null, ), ], ), diff --git a/packages/stream_chat_flutter/lib/src/message_search_list_view.dart b/packages/stream_chat_flutter/lib/src/message_search_list_view.dart index 165ed47b4..316e27b39 100644 --- a/packages/stream_chat_flutter/lib/src/message_search_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_search_list_view.dart @@ -157,53 +157,14 @@ class _MessageSearchListViewState extends State { errorBuilder: widget.errorBuilder ?? (BuildContext context, dynamic error) { if (error is Error) { - print((error).stackTrace); - } - - var message = error.toString(); - if (error is DioError) { - if (error.type == DioErrorType.RESPONSE) { - message = error.message; - } else { - message = 'Check your connection and retry'; - } + print(error.stackTrace); } return InfoTile( showMessage: widget.showErrorTile, tileAnchor: Alignment.topCenter, childAnchor: Alignment.topCenter, message: 'An error occurred.', - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text.rich( - TextSpan( - children: [ - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(right: 2.0), - child: Icon(Icons.error_outline), - ), - ), - TextSpan(text: 'Error loading messages'), - ], - ), - style: Theme.of(context).textTheme.headline6, - ), - Padding( - padding: const EdgeInsets.only(top: 16.0), - child: Text(message), - ), - ElevatedButton( - onPressed: () { - _messageSearchListController.loadData(); - }, - child: Text('Retry'), - ), - ], - ), - ), + child: Container(), ); }, loadingBuilder: widget.loadingBuilder ?? diff --git a/packages/stream_chat_flutter/lib/src/message_text.dart b/packages/stream_chat_flutter/lib/src/message_text.dart index 7557a8770..3afa60f90 100644 --- a/packages/stream_chat_flutter/lib/src/message_text.dart +++ b/packages/stream_chat_flutter/lib/src/message_text.dart @@ -21,7 +21,8 @@ class MessageText extends StatelessWidget { @override Widget build(BuildContext context) { - final text = _replaceMentions(message.text); + final text = _replaceMentions(message.text).replaceAll('\n', '\\\n'); + return MarkdownBody( data: text, onTapLink: ( diff --git a/packages/stream_chat_flutter/lib/src/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget.dart index 91c535666..7f2c83ebb 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:jiffy/jiffy.dart'; +import 'package:stream_chat_flutter/src/message_action.dart'; import 'package:stream_chat_flutter/src/message_actions_modal.dart'; import 'package:stream_chat_flutter/src/message_reactions_modal.dart'; import 'package:stream_chat_flutter/src/quoted_message_widget.dart'; @@ -143,6 +144,15 @@ class MessageWidget extends StatefulWidget { /// Function called when quotedMessage is tapped final OnQuotedMessageTap onQuotedMessageTap; + /// Function called when message is tapped + final void Function(Message) onMessageTap; + + /// List of custom actions shown on message long tap + final List customActions; + + // Customize onTap on attachment + final void Function(Message message, Attachment attachment) onAttachmentTap; + /// MessageWidget({ Key key, @@ -157,6 +167,7 @@ class MessageWidget extends StatefulWidget { this.borderRadiusGeometry, this.attachmentBorderRadiusGeometry, this.onMentionTap, + this.onMessageTap, this.showReactionPickerIndicator = false, this.showUserAvatar = DisplayWidget.show, this.showSendingIndicator = true, @@ -191,6 +202,8 @@ class MessageWidget extends StatefulWidget { this.attachmentPadding = EdgeInsets.zero, this.allRead = false, this.onQuotedMessageTap, + this.customActions = const [], + this.onAttachmentTap, }) : attachmentBuilders = { 'image': (context, message, attachment) { return ImageAttachment( @@ -203,6 +216,11 @@ class MessageWidget extends StatefulWidget { ), onShowMessage: onShowMessage, onReturnAction: onReturnAction, + onAttachmentTap: onAttachmentTap != null + ? () { + onAttachmentTap?.call(message, attachment); + } + : null, ); }, 'video': (context, message, attachment) { @@ -216,6 +234,11 @@ class MessageWidget extends StatefulWidget { message: message, onShowMessage: onShowMessage, onReturnAction: onReturnAction, + onAttachmentTap: onAttachmentTap != null + ? () { + onAttachmentTap?.call(message, attachment); + } + : null, ); }, 'giphy': (context, message, attachment) { @@ -311,6 +334,9 @@ class _MessageWidgetState extends State type: MaterialType.transparency, child: Portal( child: InkWell( + onTap: () { + widget.onMessageTap(widget.message); + }, onLongPress: widget.message.isDeleted && !isFailedState ? null : () => onLongPress(context), @@ -351,9 +377,9 @@ class _MessageWidgetState extends State portal: Container( transform: Matrix4.translationValues(-12, 0, 0), - child: _buildReactionIndicator(context), constraints: BoxConstraints(maxWidth: 22 * 6.0), + child: _buildReactionIndicator(context), ), portalAnchor: Alignment(-1.0, -1.0), childAnchor: Alignment(1, -1.0), @@ -745,6 +771,7 @@ class _MessageWidgetState extends State !isFailedState && widget.onThreadTap != null, showFlagButton: widget.showFlagButton, + customActions: widget.customActions, ), ); }); @@ -951,6 +978,7 @@ class _MessageWidgetState extends State user: widget.message.user, onTap: widget.onUserAvatarTap, constraints: widget.messageTheme.avatarTheme.constraints, + borderRadius: widget.messageTheme.avatarTheme.borderRadius, showOnlineStatus: false, ), ), diff --git a/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart b/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart index 507414199..4d2b2e387 100644 --- a/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart @@ -55,7 +55,7 @@ class _VideoAttachmentThumbnailState extends State<_VideoAttachmentThumbnail> { return Container( height: widget.size.height, width: widget.size.width, - child: _controller.value.initialized + child: _controller.value.isInitialized ? VideoPlayer(_controller) : CircularProgressIndicator()); } diff --git a/packages/stream_chat_flutter/lib/src/reaction_picker.dart b/packages/stream_chat_flutter/lib/src/reaction_picker.dart index b0aa51cea..a33e7b528 100644 --- a/packages/stream_chat_flutter/lib/src/reaction_picker.dart +++ b/packages/stream_chat_flutter/lib/src/reaction_picker.dart @@ -94,6 +94,19 @@ class _ReactionPickerState extends State height: 24, width: 24, ), + onPressed: () { + if (ownReactionIndex != -1) { + removeReaction( + context, + widget.message.ownReactions[ownReactionIndex], + ); + } else { + sendReaction( + context, + reactionIcon.type, + ); + } + }, child: AnimatedBuilder( animation: animations[index], builder: (context, val) { @@ -121,19 +134,6 @@ class _ReactionPickerState extends State ), ); }), - onPressed: () { - if (ownReactionIndex != -1) { - removeReaction( - context, - widget.message.ownReactions[ownReactionIndex], - ); - } else { - sendReaction( - context, - reactionIcon.type, - ); - } - }, ), ); }) diff --git a/packages/stream_chat_flutter/lib/src/stream_chat.dart b/packages/stream_chat_flutter/lib/src/stream_chat.dart index f093a81a3..66b49d883 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_app_badger/flutter_app_badger.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -93,9 +92,9 @@ class StreamChatState extends State { ), child: StreamChatCore( client: client, - child: widget.child, onBackgroundEventReceived: widget.onBackgroundEventReceived, backgroundKeepAlive: widget.backgroundKeepAlive, + child: widget.child, ), ); }, @@ -121,12 +120,5 @@ class StreamChatState extends State { @override void initState() { super.initState(); - client.state?.totalUnreadCountStream?.listen((count) { - if (count > 0) { - FlutterAppBadger.updateBadgeCount(count); - } else { - FlutterAppBadger.removeBadge(); - } - }); } } diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart index aa4f51f0d..eafa12c54 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart @@ -5,6 +5,7 @@ import 'package:stream_chat_flutter/src/channel_preview.dart'; import 'package:stream_chat_flutter/src/message_input.dart'; import 'package:stream_chat_flutter/src/reaction_icon.dart'; import 'package:stream_chat_flutter/src/utils.dart'; +import 'package:stream_chat_flutter/src/extension.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; /// Inherited widget providing the [StreamChatThemeData] to the widget tree @@ -45,12 +46,15 @@ class StreamChatThemeData { /// The text themes used in the widgets final TextTheme textTheme; - /// The text themes used in the widgets + /// The color themes used in the widgets final ColorTheme colorTheme; /// Theme of the [ChannelPreview] final ChannelPreviewTheme channelPreviewTheme; + /// Theme of the [ChannelListHeader] + final ChannelListHeaderTheme channelListHeaderTheme; + /// Theme of the chat widgets dedicated to a channel final ChannelTheme channelTheme; @@ -60,7 +64,7 @@ class StreamChatThemeData { /// Theme of other users messages final MessageTheme otherMessageTheme; - /// Theme of other users messages + /// Theme dedicated to the [MessageInput] widget final MessageInputTheme messageInputTheme; /// The widget that will be built when the channel image is unavailable @@ -79,6 +83,7 @@ class StreamChatThemeData { const StreamChatThemeData({ this.textTheme, this.colorTheme, + this.channelListHeaderTheme, this.channelPreviewTheme, this.channelTheme, this.otherMessageTheme, @@ -98,9 +103,7 @@ class StreamChatThemeData { accentBlue: theme.accentColor, ), defaultTheme.textTheme, - ).copyWith( - // primaryIconTheme: theme.primaryIconTheme, - ); + ); return defaultTheme.merge(customizedTheme) ?? customizedTheme; } @@ -116,9 +119,12 @@ class StreamChatThemeData { Widget Function(BuildContext, Channel) defaultChannelImage, Widget Function(BuildContext, User) defaultUserImage, IconThemeData primaryIconTheme, + ChannelListHeaderTheme channelListHeaderTheme, List reactionIcons, }) => StreamChatThemeData( + channelListHeaderTheme: + channelListHeaderTheme ?? this.channelListHeaderTheme, textTheme: textTheme ?? this.textTheme, colorTheme: colorTheme ?? this.colorTheme, primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme, @@ -135,6 +141,9 @@ class StreamChatThemeData { StreamChatThemeData merge(StreamChatThemeData other) { if (other == null) return this; return copyWith( + channelListHeaderTheme: + channelListHeaderTheme?.merge(other.channelListHeaderTheme) ?? + other.channelListHeaderTheme, textTheme: textTheme?.merge(other.textTheme) ?? other.textTheme, colorTheme: colorTheme?.merge(other.colorTheme) ?? other.colorTheme, primaryIconTheme: other.primaryIconTheme, @@ -189,6 +198,17 @@ class StreamChatThemeData { color: colorTheme.black.withOpacity(.5), ), indicatorIconSize: 16.0), + channelListHeaderTheme: ChannelListHeaderTheme( + avatarTheme: AvatarTheme( + borderRadius: BorderRadius.circular(20), + constraints: BoxConstraints.tightFor( + height: 40, + width: 40, + ), + ), + color: colorTheme.white, + title: textTheme.headlineBold, + ), channelTheme: ChannelTheme( channelHeaderTheme: ChannelHeaderTheme( avatarTheme: AvatarTheme( @@ -200,9 +220,8 @@ class StreamChatThemeData { ), color: colorTheme.white, title: textTheme.headlineBold, - lastMessageAt: TextStyle( - fontSize: 11, - color: colorTheme.black.withOpacity(.5), + subtitle: textTheme.footnote.copyWith( + color: Color(0xff7A7A7A), ), ), ), @@ -249,12 +268,26 @@ class StreamChatThemeData { ), ), messageInputTheme: MessageInputTheme( + borderRadius: BorderRadius.circular(20), sendAnimationDuration: Duration(milliseconds: 300), actionButtonColor: colorTheme.accentBlue, actionButtonIdleColor: colorTheme.grey, sendButtonColor: colorTheme.accentBlue, sendButtonIdleColor: colorTheme.greyGainsboro, inputBackground: colorTheme.white, + inputTextStyle: textTheme.body, + idleBorderGradient: LinearGradient( + colors: [ + colorTheme.greyGainsboro, + colorTheme.greyGainsboro, + ], + ), + activeBorderGradient: LinearGradient( + colors: [ + colorTheme.greyGainsboro, + colorTheme.greyGainsboro, + ], + ), ), reactionIcons: [ ReactionIcon( @@ -809,26 +842,26 @@ class ChannelPreviewTheme { class ChannelHeaderTheme { final TextStyle title; - final TextStyle lastMessageAt; + final TextStyle subtitle; final AvatarTheme avatarTheme; final Color color; const ChannelHeaderTheme({ this.title, - this.lastMessageAt, + this.subtitle, this.avatarTheme, this.color, }); ChannelHeaderTheme copyWith({ TextStyle title, - TextStyle lastMessageAt, + TextStyle subtitle, AvatarTheme avatarTheme, Color color, }) => ChannelHeaderTheme( title: title ?? this.title, - lastMessageAt: lastMessageAt ?? this.lastMessageAt, + subtitle: subtitle ?? this.subtitle, avatarTheme: avatarTheme ?? this.avatarTheme, color: color ?? this.color, ); @@ -837,8 +870,48 @@ class ChannelHeaderTheme { if (other == null) return this; return copyWith( title: title?.merge(other.title) ?? other.title, - lastMessageAt: - lastMessageAt?.merge(other.lastMessageAt) ?? other.lastMessageAt, + subtitle: subtitle?.merge(other.subtitle) ?? other.subtitle, + avatarTheme: avatarTheme?.merge(other.avatarTheme) ?? other.avatarTheme, + color: other.color, + ); + } +} + +/// Theme dedicated to the [ChannelListHeader] +class ChannelListHeaderTheme { + /// Style of the title text + final TextStyle title; + + /// Theme dedicated to the userAvatar + final AvatarTheme avatarTheme; + + /// Background color of the appbar + final Color color; + + /// Returns a new [ChannelListHeaderTheme] + const ChannelListHeaderTheme({ + this.title, + this.avatarTheme, + this.color, + }); + + /// Returns a new [ChannelListHeaderTheme] replacing some of its properties + ChannelListHeaderTheme copyWith({ + TextStyle title, + AvatarTheme avatarTheme, + Color color, + }) => + ChannelListHeaderTheme( + title: title ?? this.title, + avatarTheme: avatarTheme ?? this.avatarTheme, + color: color ?? this.color, + ); + + /// Merges [this] [ChannelListHeaderTheme] with the [other] + ChannelListHeaderTheme merge(ChannelListHeaderTheme other) { + if (other == null) return this; + return copyWith( + title: title?.merge(other.title) ?? other.title, avatarTheme: avatarTheme?.merge(other.avatarTheme) ?? other.avatarTheme, color: other.color, ); @@ -865,6 +938,21 @@ class MessageInputTheme { /// Background color of [MessageInput] final Color inputBackground; + /// TextStyle of [MessageInput] + final TextStyle inputTextStyle; + + /// InputDecoration of [MessageInput] + final InputDecoration inputDecoration; + + /// Border gradient when the [MessageInput] is not focused + final Gradient idleBorderGradient; + + /// Border gradient when the [MessageInput] is focused + final Gradient activeBorderGradient; + + /// Border radius of [MessageInput] + final BorderRadius borderRadius; + /// Returns a new [MessageInputTheme] const MessageInputTheme({ this.sendAnimationDuration, @@ -873,6 +961,11 @@ class MessageInputTheme { this.actionButtonIdleColor, this.sendButtonIdleColor, this.inputBackground, + this.inputTextStyle, + this.inputDecoration, + this.activeBorderGradient, + this.idleBorderGradient, + this.borderRadius, }); /// Returns a new [MessageInputTheme] replacing some of its properties @@ -883,6 +976,11 @@ class MessageInputTheme { Color sendButtonColor, Color actionButtonIdleColor, Color sendButtonIdleColor, + TextStyle inputTextStyle, + InputDecoration inputDecoration, + Gradient activeBorderGradient, + Gradient idleBorderGradient, + BorderRadius borderRadius, }) => MessageInputTheme( sendAnimationDuration: @@ -892,7 +990,12 @@ class MessageInputTheme { sendButtonColor: sendButtonColor ?? this.sendButtonColor, actionButtonIdleColor: actionButtonIdleColor ?? this.actionButtonIdleColor, + inputTextStyle: inputTextStyle ?? this.inputTextStyle, sendButtonIdleColor: sendButtonIdleColor ?? this.sendButtonIdleColor, + inputDecoration: inputDecoration ?? this.inputDecoration, + activeBorderGradient: activeBorderGradient ?? this.activeBorderGradient, + idleBorderGradient: idleBorderGradient ?? this.idleBorderGradient, + borderRadius: borderRadius ?? this.borderRadius, ); /// Merges [this] [MessageInputTheme] with the [other] @@ -905,6 +1008,12 @@ class MessageInputTheme { actionButtonIdleColor: other.actionButtonIdleColor, sendButtonColor: other.sendButtonColor, sendButtonIdleColor: other.sendButtonIdleColor, + inputTextStyle: other.inputTextStyle, + inputDecoration: inputDecoration?.merge(other.inputDecoration) ?? + other.inputDecoration, + activeBorderGradient: other.activeBorderGradient, + idleBorderGradient: other.idleBorderGradient, + borderRadius: other.borderRadius, ); } } diff --git a/packages/stream_chat_flutter/lib/src/stream_neumorphic_button.dart b/packages/stream_chat_flutter/lib/src/stream_neumorphic_button.dart index bf3e8e97a..35e989607 100644 --- a/packages/stream_chat_flutter/lib/src/stream_neumorphic_button.dart +++ b/packages/stream_chat_flutter/lib/src/stream_neumorphic_button.dart @@ -13,7 +13,6 @@ class StreamNeumorphicButton extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - child: child, margin: EdgeInsets.all(8.0), height: 40, width: 40, @@ -35,6 +34,7 @@ class StreamNeumorphicButton extends StatelessWidget { ), ], ), + child: child, ); } } diff --git a/packages/stream_chat_flutter/lib/src/stream_svg_icon.dart b/packages/stream_chat_flutter/lib/src/stream_svg_icon.dart index fa5d9dc4a..374b9ba16 100644 --- a/packages/stream_chat_flutter/lib/src/stream_svg_icon.dart +++ b/packages/stream_chat_flutter/lib/src/stream_svg_icon.dart @@ -18,24 +18,15 @@ class StreamSvgIcon extends StatelessWidget { @override Widget build(BuildContext context) { final key = Key('StreamSvgIcon-$assetName'); - return kIsWeb - ? Image.network( - 'packages/stream_chat_flutter/svgs/$assetName', - width: width, - height: height, - key: key, - color: color, - alignment: Alignment.center, - ) - : SvgPicture.asset( - 'lib/svgs/$assetName', - package: 'stream_chat_flutter', - key: key, - width: width, - height: height, - color: color, - alignment: Alignment.center, - ); + return SvgPicture.asset( + 'lib/svgs/$assetName', + package: 'stream_chat_flutter', + key: key, + width: width, + height: height, + color: color, + alignment: Alignment.center, + ); } factory StreamSvgIcon.settings({ diff --git a/packages/stream_chat_flutter/lib/src/system_message.dart b/packages/stream_chat_flutter/lib/src/system_message.dart index 7b4dc243d..ac3176ce6 100644 --- a/packages/stream_chat_flutter/lib/src/system_message.dart +++ b/packages/stream_chat_flutter/lib/src/system_message.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:jiffy/jiffy.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// It shows a date divider depending on the date difference @@ -18,37 +17,7 @@ class SystemMessage extends StatelessWidget { @override Widget build(BuildContext context) { - final divider = Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Divider(), - ), - ); - - final createdAt = Jiffy(message.createdAt.toLocal()); - final now = DateTime.now(); - final hourInfo = createdAt.format('h:mm a'); - - String dayInfo; - if (Jiffy(createdAt).isSame(now, Units.DAY)) { - dayInfo = 'TODAY'; - } else if (Jiffy(createdAt) - .isSame(now.subtract(Duration(days: 1)), Units.DAY)) { - dayInfo = 'YESTERDAY'; - } else if (Jiffy(createdAt).isAfter( - now.subtract(Duration(days: 7)), - Units.DAY, - )) { - dayInfo = createdAt.format('EEEE').toUpperCase(); - } else if (Jiffy(createdAt).isAfter( - Jiffy(now).subtract(years: 1), - Units.DAY, - )) { - dayInfo = createdAt.format('dd/MM').toUpperCase(); - } else { - dayInfo = createdAt.format('dd/MM/yyyy').toUpperCase(); - } - + final theme = StreamChatTheme.of(context); return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { @@ -56,59 +25,12 @@ class SystemMessage extends StatelessWidget { onMessageTap(message); } }, - child: Container( - width: double.infinity, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - divider, - Padding( - padding: const EdgeInsets.symmetric(horizontal: 32.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - message.text, - style: TextStyle( - fontSize: 10, - color: Theme.of(context) - .textTheme - .headline6 - .color - .withOpacity(.5), - fontWeight: FontWeight.bold, - ), - ), - Text.rich( - TextSpan( - children: [ - TextSpan( - text: dayInfo, - style: TextStyle( - fontWeight: FontWeight.bold, - ), - ), - TextSpan(text: ' AT'), - TextSpan(text: ' $hourInfo'), - ], - style: TextStyle( - fontWeight: FontWeight.normal, - ), - ), - style: TextStyle( - fontSize: 10, - color: Theme.of(context) - .textTheme - .headline6 - .color - .withOpacity(.5), - ), - ), - ], - ), - ), - divider, - ], + child: Text( + message.text, + textAlign: TextAlign.center, + softWrap: true, + style: theme.textTheme.captionBold.copyWith( + color: theme.colorTheme.grey, ), ), ); diff --git a/packages/stream_chat_flutter/lib/src/thread_header.dart b/packages/stream_chat_flutter/lib/src/thread_header.dart index b33b8bc18..449d45842 100644 --- a/packages/stream_chat_flutter/lib/src/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/thread_header.dart @@ -63,15 +63,35 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { /// By default it calls [Navigator.pop] final VoidCallback onBackPressed; + /// Callback to call when the title is tapped. + final VoidCallback onTitleTap; + /// The message parent of this thread final Message parent; + /// Title widget + final Widget title; + + /// Subtitle widget + final Widget subtitle; + + /// Leading widget + final Widget leading; + + /// AppBar actions + final List actions; + /// Instantiate a new ThreadHeader ThreadHeader({ Key key, @required this.parent, this.showBackButton = true, this.onBackPressed, + this.title, + this.subtitle, + this.leading, + this.actions, + this.onTitleTap, }) : preferredSize = Size.fromHeight(kToolbarHeight), super(key: key); @@ -81,51 +101,61 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { automaticallyImplyLeading: false, brightness: Theme.of(context).brightness, elevation: 1, - leading: showBackButton - ? StreamBackButton( - cid: StreamChannel.of(context).channel.cid, - onPressed: onBackPressed, - showUnreads: true, - ) - : SizedBox(), + leading: leading ?? + (showBackButton + ? StreamBackButton( + cid: StreamChannel.of(context).channel.cid, + onPressed: onBackPressed, + showUnreads: true, + ) + : SizedBox()), backgroundColor: StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color, centerTitle: true, - title: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Thread Reply', - style: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .title, - ), - SizedBox(height: 2), - Row( - mainAxisSize: MainAxisSize.min, + actions: actions, + title: InkWell( + onTap: onTitleTap, + child: Container( + height: preferredSize.height, + child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( - 'with ', - style: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .lastMessageAt, - ), - Flexible( - child: ChannelName( - textStyle: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .lastMessageAt, - ), - ), + title ?? + Text( + 'Thread Reply', + style: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .title, + ), + SizedBox(height: 2), + subtitle ?? + Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'with ', + style: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .subtitle, + ), + Flexible( + child: ChannelName( + textStyle: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .subtitle, + ), + ), + ], + ), ], ), - ], + ), ), ); } diff --git a/packages/stream_chat_flutter/lib/src/unread_indicator.dart b/packages/stream_chat_flutter/lib/src/unread_indicator.dart index cf115f3b3..61a929870 100644 --- a/packages/stream_chat_flutter/lib/src/unread_indicator.dart +++ b/packages/stream_chat_flutter/lib/src/unread_indicator.dart @@ -14,41 +14,43 @@ class UnreadIndicator extends StatelessWidget { @override Widget build(BuildContext context) { final client = StreamChat.of(context).client; - return StreamBuilder( - stream: cid != null - ? client.state.channels[cid].state.unreadCountStream - : client.state.totalUnreadCountStream, - initialData: cid != null - ? client.state.channels[cid].state.unreadCount - : client.state.totalUnreadCount, - builder: (context, snapshot) { - if (!snapshot.hasData || snapshot.data == 0) { - return SizedBox(); - } - return Material( - borderRadius: BorderRadius.circular(8), - color: StreamChatTheme.of(context) - .channelPreviewTheme - .unreadCounterColor, - child: Padding( - padding: const EdgeInsets.only( - left: 5.0, - right: 5.0, - top: 2, - bottom: 1, - ), - child: Center( - child: Text( - '${snapshot.data}', - style: TextStyle( - fontSize: 11, - color: Colors.white, + return IgnorePointer( + child: StreamBuilder( + stream: cid != null + ? client.state.channels[cid].state.unreadCountStream + : client.state.totalUnreadCountStream, + initialData: cid != null + ? client.state.channels[cid].state.unreadCount + : client.state.totalUnreadCount, + builder: (context, snapshot) { + if (!snapshot.hasData || snapshot.data == 0) { + return SizedBox(); + } + return Material( + borderRadius: BorderRadius.circular(8), + color: StreamChatTheme.of(context) + .channelPreviewTheme + .unreadCounterColor, + child: Padding( + padding: const EdgeInsets.only( + left: 5.0, + right: 5.0, + top: 2, + bottom: 1, + ), + child: Center( + child: Text( + '${snapshot.data}', + style: TextStyle( + fontSize: 11, + color: Colors.white, + ), ), ), ), - ), - ); - }, + ); + }, + ), ); } } diff --git a/packages/stream_chat_flutter/lib/src/url_attachment.dart b/packages/stream_chat_flutter/lib/src/url_attachment.dart index b0584bce0..9dc5cdc8f 100644 --- a/packages/stream_chat_flutter/lib/src/url_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/url_attachment.dart @@ -28,6 +28,9 @@ class UrlAttachment extends StatelessWidget { Container( clipBehavior: Clip.antiAliasWithSaveLayer, margin: EdgeInsets.symmetric(horizontal: 8.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.0), + ), child: Stack( children: [ CachedNetworkImage( @@ -39,6 +42,12 @@ class UrlAttachment extends StatelessWidget { left: 0.0, bottom: -1, child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topRight: Radius.circular(16.0), + ), + color: StreamChatTheme.of(context).colorTheme.blueAlice, + ), child: Padding( padding: const EdgeInsets.only( top: 8.0, @@ -57,19 +66,10 @@ class UrlAttachment extends StatelessWidget { ), ), ), - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topRight: Radius.circular(16.0), - ), - color: StreamChatTheme.of(context).colorTheme.blueAlice, - ), ), ), ], ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8.0), - ), ), Padding( padding: textPadding, diff --git a/packages/stream_chat_flutter/lib/src/user_avatar.dart b/packages/stream_chat_flutter/lib/src/user_avatar.dart index f38a9a68b..41860a7f1 100644 --- a/packages/stream_chat_flutter/lib/src/user_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/user_avatar.dart @@ -39,26 +39,29 @@ class UserAvatar extends StatelessWidget { user.extraData['image'] != ''; final streamChatTheme = StreamChatTheme.of(context); - Widget avatar = ClipRRect( - clipBehavior: Clip.antiAlias, - borderRadius: borderRadius ?? - streamChatTheme.ownMessageTheme.avatarTheme.borderRadius, - child: Container( - constraints: constraints ?? - streamChatTheme.ownMessageTheme.avatarTheme.constraints, - decoration: BoxDecoration( - color: streamChatTheme.colorTheme.accentBlue, + Widget avatar = FittedBox( + fit: BoxFit.cover, + child: ClipRRect( + clipBehavior: Clip.antiAlias, + borderRadius: borderRadius ?? + streamChatTheme.ownMessageTheme.avatarTheme.borderRadius, + child: Container( + constraints: constraints ?? + streamChatTheme.ownMessageTheme.avatarTheme.constraints, + decoration: BoxDecoration( + color: streamChatTheme.colorTheme.accentBlue, + ), + child: hasImage + ? CachedNetworkImage( + filterQuality: FilterQuality.high, + imageUrl: user.extraData['image'], + errorWidget: (_, __, ___) { + return streamChatTheme.defaultUserImage(context, user); + }, + fit: BoxFit.cover, + ) + : streamChatTheme.defaultUserImage(context, user), ), - child: hasImage - ? CachedNetworkImage( - filterQuality: FilterQuality.high, - imageUrl: user.extraData['image'], - errorWidget: (_, __, ___) { - return streamChatTheme.defaultUserImage(context, user); - }, - fit: BoxFit.cover, - ) - : streamChatTheme.defaultUserImage(context, user), ), ); @@ -91,6 +94,7 @@ class UserAvatar extends StatelessWidget { alignment: onlineIndicatorAlignment, child: Material( type: MaterialType.circle, + color: streamChatTheme.colorTheme.white, child: Container( margin: const EdgeInsets.all(2.0), constraints: onlineIndicatorConstraints ?? @@ -103,7 +107,6 @@ class UserAvatar extends StatelessWidget { color: streamChatTheme.colorTheme.accentGreen, ), ), - color: streamChatTheme.colorTheme.white, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/utils.dart b/packages/stream_chat_flutter/lib/src/utils.dart index 7a88ee6cd..8d59757e0 100644 --- a/packages/stream_chat_flutter/lib/src/utils.dart +++ b/packages/stream_chat_flutter/lib/src/utils.dart @@ -36,63 +36,74 @@ Future showConfirmationDialog( )), builder: (context) { final effect = StreamChatTheme.of(context).colorTheme.borderTop; - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(height: 26.0), - if (icon != null) icon, - SizedBox(height: 26.0), - Text( - title, - style: StreamChatTheme.of(context).textTheme.headlineBold, - ), - SizedBox(height: 7.0), - Text( - question, - textAlign: TextAlign.center, - ), - SizedBox(height: 36.0), - Container( - color: effect.color.withOpacity(effect.alpha ?? 1), - height: 1, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - TextButton( - child: Text( - cancelText, - style: StreamChatTheme.of(context) - .textTheme - .bodyBold - .copyWith( - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(0.5)), + return SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 26.0), + if (icon != null) icon, + SizedBox(height: 26.0), + Text( + title, + style: StreamChatTheme.of(context).textTheme.headlineBold, + ), + SizedBox(height: 7.0), + Text( + question, + textAlign: TextAlign.center, + ), + SizedBox(height: 36.0), + Container( + color: effect.color.withOpacity(effect.alpha ?? 1), + height: 1, + ), + Row( + children: [ + Flexible( + child: Container( + alignment: Alignment.center, + child: TextButton( + onPressed: () { + Navigator.of(context).pop(false); + }, + child: Text( + cancelText, + style: StreamChatTheme.of(context) + .textTheme + .bodyBold + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5)), + ), + ), + ), ), - onPressed: () { - Navigator.of(context).pop(false); - }, - ), - TextButton( - child: Text( - okText, - style: StreamChatTheme.of(context) - .textTheme - .bodyBold - .copyWith( - color: StreamChatTheme.of(context) - .colorTheme - .accentRed), + Flexible( + child: Container( + alignment: Alignment.center, + child: TextButton( + onPressed: () { + Navigator.pop(context, true); + }, + child: Text( + okText, + style: StreamChatTheme.of(context) + .textTheme + .bodyBold + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .accentRed), + ), + ), + ), ), - onPressed: () { - Navigator.pop(context, true); - }, - ), - ], - ), - ], + ], + ), + ], + ), ); }); } @@ -101,13 +112,13 @@ Future showInfoDialog( BuildContext context, { String title, Widget icon, - String question, + String details, String okText, StreamChatThemeData theme, }) { return showModalBottomSheet( - backgroundColor: - theme.colorTheme.white ?? StreamChatTheme.of(context).colorTheme.white, + backgroundColor: theme?.colorTheme?.white ?? + StreamChatTheme.of(context).colorTheme.white, context: context, shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( @@ -115,54 +126,51 @@ Future showInfoDialog( topRight: Radius.circular(16.0), )), builder: (context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - height: 26.0, - ), - if (icon != null) icon, - SizedBox( - height: 26.0, - ), - Text( - title, - style: theme.textTheme.headlineBold ?? - StreamChatTheme.of(context).textTheme.headlineBold, - ), - SizedBox( - height: 7.0, - ), - Text(question), - SizedBox( - height: 36.0, - ), - Container( - color: theme.colorTheme.black.withOpacity(.08) ?? - StreamChatTheme.of(context).colorTheme.black.withOpacity(.08), - height: 1.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - TextButton( + return SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 26.0, + ), + if (icon != null) icon, + SizedBox( + height: 26.0, + ), + Text( + title, + style: theme?.textTheme?.headlineBold ?? + StreamChatTheme.of(context).textTheme.headlineBold, + ), + SizedBox( + height: 7.0, + ), + Text(details), + SizedBox( + height: 36.0, + ), + Container( + color: theme?.colorTheme?.black?.withOpacity(.08) ?? + StreamChatTheme.of(context).colorTheme.black.withOpacity(.08), + height: 1.0, + ), + Center( + child: TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, child: Text( okText, style: TextStyle( - color: theme.colorTheme.black.withOpacity(0.5) ?? - StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(0.5), - fontWeight: FontWeight.w400), + color: theme?.colorTheme?.black?.withOpacity(0.5) ?? + StreamChatTheme.of(context).colorTheme.accentBlue, + fontWeight: FontWeight.w400, + ), ), - onPressed: () { - Navigator.of(context).pop(); - }, ), - ], - ), - ], + ), + ], + ), ); }, ); diff --git a/packages/stream_chat_flutter/lib/src/video_thumbnail_image.dart b/packages/stream_chat_flutter/lib/src/video_thumbnail_image.dart index 70a300054..80607b8e2 100644 --- a/packages/stream_chat_flutter/lib/src/video_thumbnail_image.dart +++ b/packages/stream_chat_flutter/lib/src/video_thumbnail_image.dart @@ -1,6 +1,8 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:video_thumbnail/video_thumbnail.dart'; import 'stream_svg_icon.dart'; @@ -65,17 +67,27 @@ class _VideoThumbnailImageState extends State { builder: (_) { if (snapshot.hasError) { return widget.errorBuilder?.call(context, snapshot.error) ?? - Center(child: StreamSvgIcon.error()); + Center( + child: StreamSvgIcon.error(), + ); } if (!snapshot.hasData) { - return widget.placeholderBuilder?.call(context) ?? - Image.asset( - 'images/placeholder.png', - package: 'stream_chat_flutter', - fit: widget.fit, - height: widget.height, - width: widget.width, - ); + return Container( + constraints: BoxConstraints.expand(), + child: widget.placeholderBuilder?.call(context) ?? + Shimmer.fromColors( + baseColor: StreamChatTheme.of(context) + .colorTheme + .greyGainsboro, + highlightColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, + child: Image.asset( + 'images/placeholder.png', + fit: BoxFit.cover, + package: 'stream_chat_flutter', + ), + ), + ); } return Image.memory( snapshot.data, diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 6fc905b5f..74c0c33e2 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -7,6 +7,7 @@ export 'src/channel_name.dart'; export 'src/channel_preview.dart'; export 'src/date_divider.dart'; export 'src/deleted_message.dart'; +export 'src/message_action.dart'; export 'src/attachment/attachment.dart'; export 'src/full_screen_media.dart'; export 'src/image_header.dart'; diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index a18801630..9cc6fe501 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 1.3.2-beta +version: 1.4.0-beta repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -11,21 +11,20 @@ environment: dependencies: flutter: sdk: flutter - stream_chat_flutter_core: ^1.3.2-beta - flutter_app_badger: ^1.1.2 - photo_view: ^0.10.3 + stream_chat_flutter_core: ^1.4.0-beta + photo_view: ^0.11.0 rxdart: ^0.25.0 scrollable_positioned_list: ^0.1.8 jiffy: ^3.0.1 - flutter_svg: ^0.19.1 + flutter_svg: ^0.19.3 flutter_portal: ^0.3.0 cached_network_image: ^2.5.0 shimmer: ^1.1.2 flutter_markdown: ^0.5.2 url_launcher: ^5.7.10 emojis: ^0.9.3 - video_player: ^1.0.1 - chewie: ^0.12.1+1 + video_player: ^2.0.0 + chewie: ^1.0.0 file_picker: ^2.1.5 image_picker: ^0.6.7+17 flutter_keyboard_visibility: ^4.0.2 @@ -38,11 +37,11 @@ dependencies: flutter_slidable: ^0.5.7 clipboard: ^0.1.2+8 image_gallery_saver: ^1.6.7 - esys_flutter_share: ^1.0.2 - photo_manager: ^0.6.0 + share_plus: ^1.2.0 + photo_manager: ^1.0.0 transparent_image: ^1.0.0 ezanimation: ^0.4.1 - synchronized: ^2.2.0+2 + synchronized: ^2.1.0 characters: ^1.0.0 dio: ^3.0.10 path_provider: ^1.6.27 diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index ff7160acb..0bad0c4e2 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.4.0-beta + +* Added `MessageListCore.messageFilter` to filter messages locally +* Minor fixes and improvements + ## 1.3.2-beta * Update llc dependency diff --git a/packages/stream_chat_flutter_core/lib/src/channels_bloc.dart b/packages/stream_chat_flutter_core/lib/src/channels_bloc.dart index 836e57c8f..1ab848780 100644 --- a/packages/stream_chat_flutter_core/lib/src/channels_bloc.dart +++ b/packages/stream_chat_flutter_core/lib/src/channels_bloc.dart @@ -107,7 +107,6 @@ class ChannelsBlocState extends State sort: sortOptions, options: options, paginationParams: paginationParams, - preferOffline: onlyOffline, )) { if (clear) { _channelsController.add(channels); @@ -173,11 +172,14 @@ class ChannelsBlocState extends State })); _subscriptions.add(client - .on(EventType.channelDeleted, EventType.notificationRemovedFromChannel) + .on( + EventType.channelDeleted, + EventType.notificationRemovedFromChannel, + ) .listen((e) { final channel = e.channel; - _channelsController - .add(List.from(channels..removeWhere((c) => c.cid == channel.cid))); + _channelsController.add(List.from( + (channels ?? [])..removeWhere((c) => c.cid == channel.cid))); })); } diff --git a/packages/stream_chat_flutter_core/lib/src/message_list_core.dart b/packages/stream_chat_flutter_core/lib/src/message_list_core.dart index 64e8f2553..87f821c13 100644 --- a/packages/stream_chat_flutter_core/lib/src/message_list_core.dart +++ b/packages/stream_chat_flutter_core/lib/src/message_list_core.dart @@ -64,6 +64,7 @@ class MessageListCore extends StatefulWidget { this.showScrollToBottom = true, this.parentMessage, this.messageListController, + this.messageFilter, }) : assert(loadingBuilder != null), assert(emptyBuilder != null), assert(messageListBuilder != null), @@ -95,6 +96,9 @@ class MessageListCore extends StatefulWidget { /// first message or the parent of the conversation. final Message parentMessage; + /// Predicate used to filter messages + final bool Function(Message) messageFilter; + @override _MessageListCoreState createState() => _MessageListCoreState(); } @@ -106,6 +110,8 @@ class _MessageListCoreState extends State { bool get _isThreadConversation => widget.parentMessage != null; + OwnUser get _currentUser => streamChannel.channel.client.state.user; + int initialIndex; double initialAlignment; @@ -121,13 +127,16 @@ class _MessageListCoreState extends State { .map((threads) => threads[widget.parentMessage.id]) : streamChannel.channel.state?.messagesStream; + bool defaultFilter(Message m) { + final isMyMessage = m.user.id == _currentUser.id; + final isDeletedOrShadowed = m.isDeleted == true || m.shadowed == true; + if (isDeletedOrShadowed && !isMyMessage) return false; + return true; + } + return StreamBuilder>( - stream: messagesStream?.map((messages) => messages - ?.where((e) => - (!e.isDeleted && e.shadowed != true) || - (e.isDeleted && - e.user.id == streamChannel.channel.client.state.user.id)) - ?.toList()), + stream: messagesStream?.map((messages) => + messages?.where(widget.messageFilter ?? defaultFilter)?.toList()), builder: (context, snapshot) { if (!snapshot.hasData) { return widget.loadingBuilder(context); @@ -135,7 +144,7 @@ class _MessageListCoreState extends State { return widget.errorWidgetBuilder(context, snapshot.error); } else { final messageList = snapshot.data?.reversed?.toList() ?? []; - if (messageList.isEmpty) { + if (messageList.isEmpty && !_isThreadConversation) { if (_upToDate) { return widget.emptyBuilder(context); } diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index b289193fb..82b02b72c 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter_core homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter. -version: 1.3.2-beta +version: 1.4.0-beta repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -10,7 +10,7 @@ environment: flutter: ">=1.17.0" dependencies: - stream_chat: ^1.3.2-beta + stream_chat: ^1.4.0-beta flutter: sdk: flutter rxdart: ^0.25.0 diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index fab0e8741..161f2d596 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.4.0-beta + +* Update llc dependency + ## 1.3.0-beta * Update llc dependency diff --git a/packages/stream_chat_persistence/example/pubspec.yaml b/packages/stream_chat_persistence/example/pubspec.yaml index f70d9d93d..faa4fcd47 100644 --- a/packages/stream_chat_persistence/example/pubspec.yaml +++ b/packages/stream_chat_persistence/example/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.0 - stream_chat: ^1.3.0 + stream_chat: ^1.4.0 stream_chat_persistence: path: ../ diff --git a/packages/stream_chat_persistence/pubspec.yaml b/packages/stream_chat_persistence/pubspec.yaml index 6923e9278..b82269ca9 100644 --- a/packages/stream_chat_persistence/pubspec.yaml +++ b/packages/stream_chat_persistence/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_persistence homepage: https://github.com/GetStream/stream-chat-flutter description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter. -version: 1.3.0-beta +version: 1.4.0-beta repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -15,7 +15,7 @@ dependencies: path: ^1.7.0 path_provider: ^1.6.27 sqlite3_flutter_libs: ^0.4.0+1 - stream_chat: ^1.3.0-beta + stream_chat: ^1.4.0-beta dev_dependencies: test: ^1.15.7

QULmQUWLDbB-F+uFCqHv&u)y8O= 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