Merge branches 'develop' and 'persistence/add-tests' of https://github.com/GetStream/stream-chat-flutter into persistence/add-tests
Conflicts: packages/stream_chat_persistence/analysis_options.yaml packages/stream_chat_persistence/lib/src/dao/channel_query_dao.dart packages/stream_chat_persistence/lib/src/dao/message_dao.dart packages/stream_chat_persistence/lib/src/dao/user_dao.dart packages/stream_chat_persistence/lib/src/db/moor_chat_database.dart packages/stream_chat_persistence/lib/src/db/shared/native_db.dart packages/stream_chat_persistence/lib/src/db/shared/unsupported_db.dart packages/stream_chat_persistence/lib/src/mapper/channel_mapper.dart packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart packages/stream_chat_persistence/pubspec.yaml
This commit is contained in:
@@ -20,7 +20,7 @@ jobs:
|
|||||||
repo: GetStream/flutter-samples
|
repo: GetStream/flutter-samples
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
token: ${{ secrets.GH_TOKEN }}
|
||||||
dispatch_stable:
|
dispatch_stable:
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/main'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: benc-uk/workflow-dispatch@v1
|
- uses: benc-uk/workflow-dispatch@v1
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ on:
|
|||||||
- opened
|
- opened
|
||||||
- edited
|
- edited
|
||||||
- synchronize
|
- synchronize
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
main:
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
- develop
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- 'docs/**'
|
- 'docs/**'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
if: github.base_ref == 'master'
|
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ Stream allows developers to rapidly deploy scalable feeds and chat messaging wit
|
|||||||
## Sample apps and demos
|
## Sample apps and demos
|
||||||
Our team maintains a dedicated repository for fully-fledged sample applications and demos. Consider checking out [GetStream/flutter-samples](https://github.com/GetStream/flutter-samples) to learn more or get started by looking at our latest [Stream Chat demo](https://github.com/GetStream/flutter-samples/tree/main/stream_chat_v1).
|
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).
|
||||||
|
|
||||||
|
## Free for Makers
|
||||||
|
|
||||||
|
Stream is free for most side and hobby projects. To qualify your project/company needs to have < 5 team members and < $10k in monthly revenue.
|
||||||
|
For complete pricing details visit our [Chat Pricing Page](https://getstream.io/chat/pricing/)
|
||||||
|
|
||||||
## Structure
|
## 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`.
|
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`.
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 1.5.0
|
||||||
|
|
||||||
|
- Minor fixes and improvements
|
||||||
|
|
||||||
## 1.4.0-beta
|
## 1.4.0-beta
|
||||||
|
|
||||||
- Improved attachment uploading
|
- Improved attachment uploading
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ linter:
|
|||||||
- avoid_private_typedef_functions
|
- avoid_private_typedef_functions
|
||||||
- avoid_redundant_argument_values
|
- avoid_redundant_argument_values
|
||||||
- avoid_return_types_on_setters
|
- avoid_return_types_on_setters
|
||||||
- avoid_returning_null
|
|
||||||
- avoid_returning_null_for_void
|
- avoid_returning_null_for_void
|
||||||
- avoid_shadowing_type_parameters
|
- avoid_shadowing_type_parameters
|
||||||
- avoid_single_cascade_in_expression_statements
|
- avoid_single_cascade_in_expression_statements
|
||||||
|
|||||||
@@ -1209,6 +1209,7 @@ class ChannelClientState {
|
|||||||
ChannelClientState(
|
ChannelClientState(
|
||||||
this._channel,
|
this._channel,
|
||||||
ChannelState channelState,
|
ChannelState channelState,
|
||||||
|
//ignore: unnecessary_parenthesis
|
||||||
) : _debouncedUpdatePersistenceChannelState = ((ChannelState state) {
|
) : _debouncedUpdatePersistenceChannelState = ((ChannelState state) {
|
||||||
_channel?._client?.chatPersistenceClient?.updateChannelState(state);
|
_channel?._client?.chatPersistenceClient?.updateChannelState(state);
|
||||||
}).debounced(const Duration(seconds: 1)) {
|
}).debounced(const Duration(seconds: 1)) {
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ import 'package:stream_chat/src/client.dart';
|
|||||||
/// Current package version
|
/// Current package version
|
||||||
/// Used in [StreamChatClient] to build the `x-stream-client` header
|
/// Used in [StreamChatClient] to build the `x-stream-client` header
|
||||||
// ignore: constant_identifier_names
|
// ignore: constant_identifier_names
|
||||||
const PACKAGE_VERSION = '1.4.0-beta';
|
const PACKAGE_VERSION = '1.5.0';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat
|
name: stream_chat
|
||||||
homepage: https://getstream.io/
|
homepage: https://getstream.io/
|
||||||
description: The official Dart client for Stream Chat, a service for building chat applications.
|
description: The official Dart client for Stream Chat, a service for building chat applications.
|
||||||
version: 1.4.0-beta
|
version: 1.5.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
## 1.5.1
|
||||||
|
|
||||||
|
- Fixed unread count not updating while the chat is open
|
||||||
|
|
||||||
|
## 1.5.0
|
||||||
|
|
||||||
|
- Fixed swipeable visible on navigation back
|
||||||
|
- Fixed video upload
|
||||||
|
- `MessageInput`: added more actions locations, merge actions and add `showCommandsButton` property
|
||||||
|
- 🛑 **BREAKING** Updated AttachmentBuilder signature
|
||||||
|
- Fixed image reloading on reaction.new
|
||||||
|
|
||||||
## 1.4.0-beta
|
## 1.4.0-beta
|
||||||
|
|
||||||
- Unfocus `MessageInput` only when sending commands
|
- Unfocus `MessageInput` only when sending commands
|
||||||
@@ -10,7 +22,7 @@
|
|||||||
- Added `MessageListView.onAttachmentTap` callback
|
- Added `MessageListView.onAttachmentTap` callback
|
||||||
- Fixed message newline issue
|
- Fixed message newline issue
|
||||||
- Fixed `MessageListView` scroll keyboard behaviour
|
- Fixed `MessageListView` scroll keyboard behaviour
|
||||||
- Minor fixes and improveqments
|
- Minor fixes and improvements
|
||||||
|
|
||||||
## 1.3.2-beta
|
## 1.3.2-beta
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
|||||||
import 'package:stream_chat_flutter/src/utils.dart';
|
import 'package:stream_chat_flutter/src/utils.dart';
|
||||||
import 'package:stream_chat_flutter/src/video_thumbnail_image.dart';
|
import 'package:stream_chat_flutter/src/video_thumbnail_image.dart';
|
||||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
import 'package:transparent_image/transparent_image.dart';
|
|
||||||
|
|
||||||
import '../upload_progress_indicator.dart';
|
import '../upload_progress_indicator.dart';
|
||||||
import 'attachment_widget.dart';
|
import 'attachment_widget.dart';
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shimmer/shimmer.dart';
|
import 'package:shimmer/shimmer.dart';
|
||||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
import 'package:transparent_image/transparent_image.dart';
|
|
||||||
|
|
||||||
import '../full_screen_media.dart';
|
import '../full_screen_media.dart';
|
||||||
import '../stream_chat_theme.dart';
|
import '../stream_chat_theme.dart';
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import 'package:shimmer/shimmer.dart';
|
|||||||
import 'package:stream_chat_flutter/src/attachment/attachment_upload_state_builder.dart';
|
import 'package:stream_chat_flutter/src/attachment/attachment_upload_state_builder.dart';
|
||||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
|
|
||||||
import 'attachment_title.dart';
|
|
||||||
import '../full_screen_media.dart';
|
import '../full_screen_media.dart';
|
||||||
import '../stream_chat_theme.dart';
|
import '../stream_chat_theme.dart';
|
||||||
|
import 'attachment_title.dart';
|
||||||
import 'attachment_widget.dart';
|
import 'attachment_widget.dart';
|
||||||
|
|
||||||
class ImageAttachment extends AttachmentWidget {
|
class ImageAttachment extends AttachmentWidget {
|
||||||
@@ -81,6 +81,7 @@ class ImageAttachment extends AttachmentWidget {
|
|||||||
return _buildImageAttachment(
|
return _buildImageAttachment(
|
||||||
context,
|
context,
|
||||||
CachedNetworkImage(
|
CachedNetworkImage(
|
||||||
|
cacheKey: imageUri.path,
|
||||||
height: size?.height,
|
height: size?.height,
|
||||||
width: size?.width,
|
width: size?.width,
|
||||||
placeholder: (_, __) {
|
placeholder: (_, __) {
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:stream_chat_flutter/src/message_action.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/reaction_picker.dart';
|
||||||
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
||||||
import 'package:stream_chat_flutter/src/utils.dart';
|
import 'package:stream_chat_flutter/src/utils.dart';
|
||||||
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
|
||||||
import 'extension.dart';
|
import 'extension.dart';
|
||||||
import 'message_input.dart';
|
import 'message_input.dart';
|
||||||
@@ -34,6 +34,7 @@ class MessageActionsModal extends StatefulWidget {
|
|||||||
final ShapeBorder messageShape;
|
final ShapeBorder messageShape;
|
||||||
final ShapeBorder attachmentShape;
|
final ShapeBorder attachmentShape;
|
||||||
final DisplayWidget showUserAvatar;
|
final DisplayWidget showUserAvatar;
|
||||||
|
final BorderRadius attachmentBorderRadiusGeometry;
|
||||||
|
|
||||||
/// List of custom actions
|
/// List of custom actions
|
||||||
final List<MessageAction> customActions;
|
final List<MessageAction> customActions;
|
||||||
@@ -58,6 +59,7 @@ class MessageActionsModal extends StatefulWidget {
|
|||||||
this.attachmentShape,
|
this.attachmentShape,
|
||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
this.customActions = const [],
|
this.customActions = const [],
|
||||||
|
this.attachmentBorderRadiusGeometry,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -153,6 +155,8 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
child: MessageWidget(
|
child: MessageWidget(
|
||||||
key: Key('MessageWidget'),
|
key: Key('MessageWidget'),
|
||||||
reverse: widget.reverse,
|
reverse: widget.reverse,
|
||||||
|
attachmentBorderRadiusGeometry:
|
||||||
|
widget.attachmentBorderRadiusGeometry,
|
||||||
message: widget.message.copyWith(
|
message: widget.message.copyWith(
|
||||||
text: widget.message.text.length > 200
|
text: widget.message.text.length > 200
|
||||||
? '${widget.message.text.substring(0, 200)}...'
|
? '${widget.message.text.substring(0, 200)}...'
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:photo_manager/photo_manager.dart';
|
import 'package:photo_manager/photo_manager.dart';
|
||||||
import 'package:shimmer/shimmer.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/media_list_view.dart';
|
||||||
import 'package:stream_chat_flutter/src/message_list_view.dart';
|
import 'package:stream_chat_flutter/src/message_list_view.dart';
|
||||||
import 'package:stream_chat_flutter/src/stream_chat_theme.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/stream_svg_icon.dart';
|
||||||
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
||||||
|
import 'package:stream_chat_flutter/src/video_service.dart';
|
||||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
import 'package:substring_highlight/substring_highlight.dart';
|
import 'package:substring_highlight/substring_highlight.dart';
|
||||||
|
|
||||||
@@ -35,6 +35,8 @@ typedef AttachmentThumbnailBuilder = Widget Function(
|
|||||||
enum ActionsLocation {
|
enum ActionsLocation {
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
|
leftInside,
|
||||||
|
rightInside,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DefaultAttachmentTypes {
|
enum DefaultAttachmentTypes {
|
||||||
@@ -122,6 +124,7 @@ class MessageInput extends StatefulWidget {
|
|||||||
this.hideSendAsDm = false,
|
this.hideSendAsDm = false,
|
||||||
this.idleSendButton,
|
this.idleSendButton,
|
||||||
this.activeSendButton,
|
this.activeSendButton,
|
||||||
|
this.showCommandsButton = true,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// Message to edit
|
/// Message to edit
|
||||||
@@ -149,6 +152,9 @@ class MessageInput extends StatefulWidget {
|
|||||||
/// If true the attachments button will not be displayed
|
/// If true the attachments button will not be displayed
|
||||||
final bool disableAttachments;
|
final bool disableAttachments;
|
||||||
|
|
||||||
|
/// Use this property to hide/show the commands button
|
||||||
|
final bool showCommandsButton;
|
||||||
|
|
||||||
/// Hide send as dm checkbox
|
/// Hide send as dm checkbox
|
||||||
final bool hideSendAsDm;
|
final bool hideSendAsDm;
|
||||||
|
|
||||||
@@ -308,7 +314,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
child: _buildTextField(context),
|
child: _buildTextField(context),
|
||||||
),
|
),
|
||||||
if (widget.parentMessage != null && !widget.hideSendAsDm)
|
if (widget.parentMessage != null && !widget.hideSendAsDm)
|
||||||
@@ -336,12 +342,11 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
direction: Axis.horizontal,
|
direction: Axis.horizontal,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (!_commandEnabled) _buildExpandActionsButton(),
|
if (!_commandEnabled && widget.actionsLocation == ActionsLocation.left)
|
||||||
if (widget.actionsLocation == ActionsLocation.left)
|
_buildExpandActionsButton(),
|
||||||
...widget.actions ?? [],
|
|
||||||
_buildTextInput(context),
|
_buildTextInput(context),
|
||||||
if (widget.actionsLocation == ActionsLocation.right)
|
if (!_commandEnabled && widget.actionsLocation == ActionsLocation.right)
|
||||||
...widget.actions ?? [],
|
_buildExpandActionsButton(),
|
||||||
if (widget.sendButtonLocation == SendButtonLocation.outside)
|
if (widget.sendButtonLocation == SendButtonLocation.outside)
|
||||||
_animateSendButton(context),
|
_animateSendButton(context),
|
||||||
],
|
],
|
||||||
@@ -421,32 +426,36 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
child: widget.activeSendButton,
|
child: widget.activeSendButton,
|
||||||
)
|
)
|
||||||
: _buildSendButton(context);
|
: _buildSendButton(context);
|
||||||
return Padding(
|
return AnimatedCrossFade(
|
||||||
padding: const EdgeInsets.all(8.0),
|
crossFadeState: (_messageIsPresent || _attachments.isNotEmpty)
|
||||||
child: AnimatedCrossFade(
|
? CrossFadeState.showFirst
|
||||||
crossFadeState: (_messageIsPresent || _attachments.isNotEmpty)
|
: CrossFadeState.showSecond,
|
||||||
? CrossFadeState.showFirst
|
firstChild: sendButton,
|
||||||
: CrossFadeState.showSecond,
|
secondChild: widget.idleSendButton ?? _buildIdleSendButton(context),
|
||||||
firstChild: sendButton,
|
duration:
|
||||||
secondChild: widget.idleSendButton ?? _buildIdleSendButton(context),
|
StreamChatTheme.of(context).messageInputTheme.sendAnimationDuration,
|
||||||
duration:
|
alignment: Alignment.center,
|
||||||
StreamChatTheme.of(context).messageInputTheme.sendAnimationDuration,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildExpandActionsButton() {
|
Widget _buildExpandActionsButton() {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
child: AnimatedCrossFade(
|
child: AnimatedCrossFade(
|
||||||
crossFadeState: _actionsShrunk
|
crossFadeState: _actionsShrunk
|
||||||
? CrossFadeState.showFirst
|
? CrossFadeState.showFirst
|
||||||
: CrossFadeState.showSecond,
|
: CrossFadeState.showSecond,
|
||||||
firstChild: IconButton(
|
firstChild: IconButton(
|
||||||
onPressed: () => setState(() => _actionsShrunk = false),
|
onPressed: () => setState(() => _actionsShrunk = false),
|
||||||
icon: StreamSvgIcon.emptyCircleLeft(
|
icon: Transform.rotate(
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
alignment: Alignment.center,
|
||||||
|
angle: (widget.actionsLocation == ActionsLocation.right ||
|
||||||
|
widget.actionsLocation == ActionsLocation.rightInside)
|
||||||
|
? pi
|
||||||
|
: 0,
|
||||||
|
child: StreamSvgIcon.emptyCircleLeft(
|
||||||
|
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
constraints: BoxConstraints.tightFor(
|
constraints: BoxConstraints.tightFor(
|
||||||
@@ -457,10 +466,12 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
),
|
),
|
||||||
secondChild: FittedBox(
|
secondChild: FittedBox(
|
||||||
child: Row(
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: <Widget>[
|
||||||
if (!widget.disableAttachments) _buildAttachmentButton(),
|
if (!widget.disableAttachments) _buildAttachmentButton(),
|
||||||
if (widget.editMessage == null &&
|
if (widget.showCommandsButton &&
|
||||||
|
widget.editMessage == null &&
|
||||||
StreamChannel.of(context)
|
StreamChannel.of(context)
|
||||||
.channel
|
.channel
|
||||||
?.config
|
?.config
|
||||||
@@ -468,6 +479,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
?.isNotEmpty ==
|
?.isNotEmpty ==
|
||||||
true)
|
true)
|
||||||
_buildCommandButton(),
|
_buildCommandButton(),
|
||||||
|
...widget.actions ?? [],
|
||||||
].insertBetween(const SizedBox(width: 8)),
|
].insertBetween(const SizedBox(width: 8)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -565,51 +577,75 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
contentPadding: const EdgeInsets.fromLTRB(16, 12, 13, 11),
|
contentPadding: const EdgeInsets.fromLTRB(16, 12, 13, 11),
|
||||||
prefixIconConstraints: BoxConstraints.tight(Size(78, 24)),
|
|
||||||
suffixIconConstraints: BoxConstraints.tight(Size(40, 40)),
|
|
||||||
prefixIcon: _commandEnabled
|
prefixIcon: _commandEnabled
|
||||||
? Container(
|
? Row(
|
||||||
decoration: BoxDecoration(
|
mainAxisSize: MainAxisSize.min,
|
||||||
borderRadius: BorderRadius.circular(12),
|
children: [
|
||||||
color: theme.colorTheme.accentBlue,
|
Padding(
|
||||||
),
|
padding: const EdgeInsets.all(8.0),
|
||||||
margin: const EdgeInsets.only(right: 4, left: 8),
|
child: Container(
|
||||||
alignment: Alignment.center,
|
constraints: BoxConstraints.tight(Size(64, 24)),
|
||||||
child: Row(
|
decoration: BoxDecoration(
|
||||||
mainAxisSize: MainAxisSize.min,
|
borderRadius: BorderRadius.circular(12),
|
||||||
children: [
|
color: theme.colorTheme.accentBlue,
|
||||||
StreamSvgIcon.lightning(
|
),
|
||||||
color: Colors.white,
|
alignment: Alignment.center,
|
||||||
size: 16.0,
|
child: Row(
|
||||||
),
|
mainAxisSize: MainAxisSize.min,
|
||||||
Text(
|
children: [
|
||||||
_chosenCommand?.name?.toUpperCase() ?? '',
|
StreamSvgIcon.lightning(
|
||||||
style: StreamChatTheme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.footnoteBold
|
|
||||||
.copyWith(
|
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
size: 16.0,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
_chosenCommand?.name?.toUpperCase() ?? '',
|
||||||
|
style: StreamChatTheme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.footnoteBold
|
||||||
|
.copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
)
|
)
|
||||||
: null,
|
: (widget.actionsLocation == ActionsLocation.leftInside
|
||||||
|
? Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
_buildExpandActionsButton(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: null),
|
||||||
|
suffixIconConstraints: BoxConstraints.tightFor(height: 40),
|
||||||
|
prefixIconConstraints: BoxConstraints.tightFor(height: 40),
|
||||||
suffixIcon: Row(
|
suffixIcon: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
if (_commandEnabled)
|
if (_commandEnabled)
|
||||||
IconButton(
|
Padding(
|
||||||
icon: StreamSvgIcon.closeSmall(),
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
splashRadius: 24,
|
child: IconButton(
|
||||||
padding: const EdgeInsets.all(0),
|
icon: StreamSvgIcon.closeSmall(),
|
||||||
constraints: BoxConstraints.tightFor(
|
splashRadius: 24,
|
||||||
height: 24,
|
padding: const EdgeInsets.all(0),
|
||||||
width: 24,
|
constraints: BoxConstraints.tightFor(
|
||||||
|
height: 24,
|
||||||
|
width: 24,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() => _commandEnabled = false);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
onPressed: () {
|
|
||||||
setState(() => _commandEnabled = false);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
|
if (!_commandEnabled &&
|
||||||
|
widget.actionsLocation == ActionsLocation.rightInside)
|
||||||
|
_buildExpandActionsButton(),
|
||||||
if (widget.sendButtonLocation == SendButtonLocation.inside)
|
if (widget.sendButtonLocation == SendButtonLocation.inside)
|
||||||
_animateSendButton(context),
|
_animateSendButton(context),
|
||||||
],
|
],
|
||||||
@@ -619,7 +655,13 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
Timer _debounce;
|
Timer _debounce;
|
||||||
|
|
||||||
|
String _previousValue;
|
||||||
void _onChanged(BuildContext context, String s) {
|
void _onChanged(BuildContext context, String s) {
|
||||||
|
if (s == _previousValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_previousValue = s;
|
||||||
|
|
||||||
if (_debounce?.isActive == true) _debounce.cancel();
|
if (_debounce?.isActive == true) _debounce.cancel();
|
||||||
_debounce = Timer(
|
_debounce = Timer(
|
||||||
const Duration(milliseconds: 350),
|
const Duration(milliseconds: 350),
|
||||||
@@ -631,7 +673,11 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_messageIsPresent = s.trim().isNotEmpty;
|
_messageIsPresent = s.trim().isNotEmpty;
|
||||||
_actionsShrunk = s.trim().isNotEmpty;
|
_actionsShrunk = s.trim().isNotEmpty &&
|
||||||
|
((widget.actions?.length ?? 0) +
|
||||||
|
(widget.showCommandsButton ? 1 : 0) +
|
||||||
|
(widget.disableAttachments ? 0 : 1) >
|
||||||
|
1);
|
||||||
});
|
});
|
||||||
|
|
||||||
_commandsOverlay?.remove();
|
_commandsOverlay?.remove();
|
||||||
@@ -1684,13 +1730,19 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCommandButton() {
|
Widget _buildCommandButton() {
|
||||||
|
final s = textEditingController.text.trim();
|
||||||
|
|
||||||
return IconButton(
|
return IconButton(
|
||||||
icon: StreamSvgIcon.lightning(
|
icon: StreamSvgIcon.lightning(
|
||||||
color: _commandsOverlay != null
|
color: s.isNotEmpty
|
||||||
? StreamChatTheme.of(context).messageInputTheme.actionButtonColor
|
? StreamChatTheme.of(context).colorTheme.greyGainsboro
|
||||||
: StreamChatTheme.of(context)
|
: (_commandsOverlay != null
|
||||||
.messageInputTheme
|
? StreamChatTheme.of(context)
|
||||||
.actionButtonIdleColor,
|
.messageInputTheme
|
||||||
|
.actionButtonColor
|
||||||
|
: StreamChatTheme.of(context)
|
||||||
|
.messageInputTheme
|
||||||
|
.actionButtonIdleColor),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
constraints: BoxConstraints.tightFor(
|
constraints: BoxConstraints.tightFor(
|
||||||
@@ -1711,7 +1763,9 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
if (_commandsOverlay == null) {
|
if (_commandsOverlay == null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_commandsOverlay = _buildCommandsOverlayEntry();
|
_commandsOverlay = _buildCommandsOverlayEntry();
|
||||||
Overlay.of(context).insert(_commandsOverlay);
|
if (_commandsOverlay != null) {
|
||||||
|
Overlay.of(context).insert(_commandsOverlay);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -1904,11 +1958,11 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
if (file == null) return;
|
if (file == null) return;
|
||||||
|
|
||||||
final mimeType = file.name?.mimeType;
|
final mimeType = file.name?.mimeType ?? file.path.split('/').last.mimeType;
|
||||||
|
|
||||||
final extraDataMap = <String, dynamic>{};
|
final extraDataMap = <String, dynamic>{};
|
||||||
|
|
||||||
if (mimeType.type == 'video' || mimeType.type == 'image') {
|
if (mimeType?.type == 'video' || mimeType?.type == 'image') {
|
||||||
attachmentType = mimeType.type;
|
attachmentType = mimeType.type;
|
||||||
} else {
|
} else {
|
||||||
attachmentType = 'file';
|
attachmentType = 'file';
|
||||||
@@ -1965,24 +2019,31 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildIdleSendButton(BuildContext context) {
|
Widget _buildIdleSendButton(BuildContext context) {
|
||||||
return StreamSvgIcon(
|
return Padding(
|
||||||
assetName: _getIdleSendIcon(),
|
padding: const EdgeInsets.all(8.0),
|
||||||
color: StreamChatTheme.of(context).messageInputTheme.sendButtonIdleColor,
|
child: StreamSvgIcon(
|
||||||
|
assetName: _getIdleSendIcon(),
|
||||||
|
color:
|
||||||
|
StreamChatTheme.of(context).messageInputTheme.sendButtonIdleColor,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSendButton(BuildContext context) {
|
Widget _buildSendButton(BuildContext context) {
|
||||||
return IconButton(
|
return Padding(
|
||||||
onPressed: sendMessage,
|
padding: const EdgeInsets.all(8.0),
|
||||||
padding: const EdgeInsets.all(0),
|
child: IconButton(
|
||||||
splashRadius: 24,
|
onPressed: sendMessage,
|
||||||
constraints: BoxConstraints.tightFor(
|
padding: const EdgeInsets.all(0),
|
||||||
height: 24,
|
splashRadius: 24,
|
||||||
width: 24,
|
constraints: BoxConstraints.tightFor(
|
||||||
),
|
height: 24,
|
||||||
icon: StreamSvgIcon(
|
width: 24,
|
||||||
assetName: _getSendIcon(),
|
),
|
||||||
color: StreamChatTheme.of(context).messageInputTheme.sendButtonColor,
|
icon: StreamSvgIcon(
|
||||||
|
assetName: _getSendIcon(),
|
||||||
|
color: StreamChatTheme.of(context).messageInputTheme.sendButtonColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -749,7 +749,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
Widget messageWidget;
|
Widget messageWidget;
|
||||||
if (widget.messageBuilder != null) {
|
if (widget.messageBuilder != null) {
|
||||||
messageWidget = Builder(
|
messageWidget = Builder(
|
||||||
key: ValueKey<String>('BOTTOM-MESSAGE'),
|
key: ValueKey<String>('BOTTOM-MESSAGE-${message.id}'),
|
||||||
builder: (_) => widget.messageBuilder(
|
builder: (_) => widget.messageBuilder(
|
||||||
context,
|
context,
|
||||||
MessageDetails(
|
MessageDetails(
|
||||||
@@ -766,7 +766,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return VisibilityDetector(
|
return VisibilityDetector(
|
||||||
key: ValueKey<String>('BOTTOM-MESSAGE'),
|
key: ValueKey<String>('BOTTOM-MESSAGE-${message.id}'),
|
||||||
onVisibilityChanged: (visibility) {
|
onVisibilityChanged: (visibility) {
|
||||||
final isVisible = visibility.visibleBounds != Rect.zero;
|
final isVisible = visibility.visibleBounds != Rect.zero;
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
@@ -1021,15 +1021,19 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
!message.isSystem &&
|
!message.isSystem &&
|
||||||
!message.isEphemeral &&
|
!message.isEphemeral &&
|
||||||
widget.onMessageSwiped != null) {
|
widget.onMessageSwiped != null) {
|
||||||
child = Swipeable(
|
child = Container(
|
||||||
onSwipeEnd: () {
|
decoration: BoxDecoration(),
|
||||||
FocusScope.of(context).unfocus();
|
clipBehavior: Clip.hardEdge,
|
||||||
widget.onMessageSwiped(message);
|
child: Swipeable(
|
||||||
},
|
onSwipeEnd: () {
|
||||||
backgroundIcon: StreamSvgIcon.reply(
|
FocusScope.of(context).unfocus();
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
widget.onMessageSwiped(message);
|
||||||
|
},
|
||||||
|
backgroundIcon: StreamSvgIcon.reply(
|
||||||
|
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
|
),
|
||||||
|
child: child,
|
||||||
),
|
),
|
||||||
child: Container(child: child),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stream_chat_flutter/src/message_action.dart';
|
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
|
||||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
|
||||||
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
|
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
|
||||||
import 'package:stream_chat_flutter/src/reaction_picker.dart';
|
import 'package:stream_chat_flutter/src/reaction_picker.dart';
|
||||||
import 'package:stream_chat_flutter/src/stream_chat.dart';
|
import 'package:stream_chat_flutter/src/stream_chat.dart';
|
||||||
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
||||||
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
|
|
||||||
|
import 'extension.dart';
|
||||||
import 'message_widget.dart';
|
import 'message_widget.dart';
|
||||||
import 'stream_chat_theme.dart';
|
import 'stream_chat_theme.dart';
|
||||||
import 'extension.dart';
|
|
||||||
|
|
||||||
class MessageReactionsModal extends StatelessWidget {
|
class MessageReactionsModal extends StatelessWidget {
|
||||||
final Widget Function(BuildContext, Message) editMessageInputBuilder;
|
final Widget Function(BuildContext, Message) editMessageInputBuilder;
|
||||||
@@ -24,6 +23,7 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
final ShapeBorder messageShape;
|
final ShapeBorder messageShape;
|
||||||
final ShapeBorder attachmentShape;
|
final ShapeBorder attachmentShape;
|
||||||
final void Function(User) onUserAvatarTap;
|
final void Function(User) onUserAvatarTap;
|
||||||
|
final BorderRadius attachmentBorderRadiusGeometry;
|
||||||
|
|
||||||
const MessageReactionsModal({
|
const MessageReactionsModal({
|
||||||
Key key,
|
Key key,
|
||||||
@@ -37,6 +37,7 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
this.showUserAvatar = DisplayWidget.show,
|
this.showUserAvatar = DisplayWidget.show,
|
||||||
this.onUserAvatarTap,
|
this.onUserAvatarTap,
|
||||||
|
this.attachmentBorderRadiusGeometry,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -133,6 +134,8 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
shape: messageShape,
|
shape: messageShape,
|
||||||
attachmentShape: attachmentShape,
|
attachmentShape: attachmentShape,
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
|
attachmentBorderRadiusGeometry:
|
||||||
|
attachmentBorderRadiusGeometry,
|
||||||
attachmentPadding: EdgeInsets.all(
|
attachmentPadding: EdgeInsets.all(
|
||||||
hasFileAttachment ? 4 : 2,
|
hasFileAttachment ? 4 : 2,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ class MessageWidget extends StatefulWidget {
|
|||||||
),
|
),
|
||||||
border,
|
border,
|
||||||
reverse,
|
reverse,
|
||||||
|
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -259,6 +260,7 @@ class MessageWidget extends StatefulWidget {
|
|||||||
),
|
),
|
||||||
border,
|
border,
|
||||||
reverse,
|
reverse,
|
||||||
|
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'video': (context, message, attachments) {
|
'video': (context, message, attachments) {
|
||||||
@@ -291,6 +293,7 @@ class MessageWidget extends StatefulWidget {
|
|||||||
),
|
),
|
||||||
border,
|
border,
|
||||||
reverse,
|
reverse,
|
||||||
|
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'giphy': (context, message, attachments) {
|
'giphy': (context, message, attachments) {
|
||||||
@@ -318,6 +321,7 @@ class MessageWidget extends StatefulWidget {
|
|||||||
),
|
),
|
||||||
border,
|
border,
|
||||||
reverse,
|
reverse,
|
||||||
|
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'file': (context, message, attachments) {
|
'file': (context, message, attachments) {
|
||||||
@@ -329,22 +333,28 @@ class MessageWidget extends StatefulWidget {
|
|||||||
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
);
|
);
|
||||||
|
|
||||||
return wrapAttachmentWidget(
|
return Column(
|
||||||
context,
|
children: attachments
|
||||||
Column(
|
.map<Widget>((attachment) {
|
||||||
children: attachments.map((attachment) {
|
return wrapAttachmentWidget(
|
||||||
return FileAttachment(
|
context,
|
||||||
message: message,
|
FileAttachment(
|
||||||
attachment: attachment,
|
message: message,
|
||||||
size: Size(
|
attachment: attachment,
|
||||||
MediaQuery.of(context).size.width * 0.8,
|
size: Size(
|
||||||
MediaQuery.of(context).size.height * 0.3,
|
MediaQuery.of(context).size.width * 0.8,
|
||||||
),
|
MediaQuery.of(context).size.height * 0.3,
|
||||||
);
|
),
|
||||||
}).toList(),
|
),
|
||||||
),
|
border,
|
||||||
border,
|
reverse,
|
||||||
reverse,
|
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.insertBetween(SizedBox(
|
||||||
|
height: attachmentPadding.vertical / 2,
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}..addAll(customAttachmentBuilders ?? {}),
|
}..addAll(customAttachmentBuilders ?? {}),
|
||||||
@@ -822,6 +832,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
return StreamChannel(
|
return StreamChannel(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
child: MessageActionsModal(
|
child: MessageActionsModal(
|
||||||
|
attachmentBorderRadiusGeometry:
|
||||||
|
widget.attachmentBorderRadiusGeometry,
|
||||||
showUserAvatar:
|
showUserAvatar:
|
||||||
widget.message.user.id == channel.client.state.user.id
|
widget.message.user.id == channel.client.state.user.id
|
||||||
? DisplayWidget.gone
|
? DisplayWidget.gone
|
||||||
@@ -869,6 +881,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
return StreamChannel(
|
return StreamChannel(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
child: MessageReactionsModal(
|
child: MessageReactionsModal(
|
||||||
|
attachmentBorderRadiusGeometry:
|
||||||
|
widget.attachmentBorderRadiusGeometry,
|
||||||
showUserAvatar:
|
showUserAvatar:
|
||||||
widget.message.user.id == channel.client.state.user.id
|
widget.message.user.id == channel.client.state.user.id
|
||||||
? DisplayWidget.gone
|
? DisplayWidget.gone
|
||||||
@@ -913,7 +927,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _parseAttachments() {
|
Widget _parseAttachments() {
|
||||||
Map<String, List<Attachment>> attachmentGroups = {};
|
final attachmentGroups = <String, List<Attachment>>{};
|
||||||
|
|
||||||
widget.message.attachments
|
widget.message.attachments
|
||||||
.where((element) => element.ogScrapeUrl == null)
|
.where((element) => element.ogScrapeUrl == null)
|
||||||
@@ -925,7 +939,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
attachmentGroups[e.type].add(e);
|
attachmentGroups[e.type].add(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
List<Widget> attachmentList = [];
|
final attachmentList = <Widget>[];
|
||||||
|
|
||||||
attachmentGroups.forEach((type, attachments) {
|
attachmentGroups.forEach((type, attachments) {
|
||||||
final attachmentBuilder = widget.attachmentBuilders[type];
|
final attachmentBuilder = widget.attachmentBuilders[type];
|
||||||
|
|||||||
@@ -356,15 +356,19 @@ Widget wrapAttachmentWidget(
|
|||||||
Widget attachmentWidget,
|
Widget attachmentWidget,
|
||||||
ShapeBorder attachmentShape,
|
ShapeBorder attachmentShape,
|
||||||
bool reverse,
|
bool reverse,
|
||||||
|
BorderRadius borderRadius,
|
||||||
) {
|
) {
|
||||||
return Material(
|
return ClipRRect(
|
||||||
clipBehavior: Clip.antiAlias,
|
borderRadius: borderRadius,
|
||||||
shape: attachmentShape,
|
child: Material(
|
||||||
type: MaterialType.transparency,
|
clipBehavior: Clip.antiAlias,
|
||||||
child: Transform(
|
shape: attachmentShape,
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
type: MaterialType.transparency,
|
||||||
alignment: Alignment.center,
|
child: Transform(
|
||||||
child: attachmentWidget,
|
transform: Matrix4.rotationY(reverse ? pi : 0),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: attachmentWidget,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_flutter
|
name: stream_chat_flutter
|
||||||
homepage: https://github.com/GetStream/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.
|
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
||||||
version: 1.4.0-beta
|
version: 1.5.1
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -11,11 +11,7 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
stream_chat_flutter_core:
|
stream_chat_flutter_core: ^1.5.0
|
||||||
git:
|
|
||||||
url: https://github.com/GetStream/stream-chat-flutter.git
|
|
||||||
ref: develop
|
|
||||||
path: packages/stream_chat_flutter_core
|
|
||||||
photo_view: ^0.11.0
|
photo_view: ^0.11.0
|
||||||
rxdart: ^0.25.0
|
rxdart: ^0.25.0
|
||||||
scrollable_positioned_list: ^0.1.8
|
scrollable_positioned_list: ^0.1.8
|
||||||
@@ -34,16 +30,13 @@ dependencies:
|
|||||||
flutter_keyboard_visibility: ^4.0.2
|
flutter_keyboard_visibility: ^4.0.2
|
||||||
video_compress: ^2.1.1
|
video_compress: ^2.1.1
|
||||||
visibility_detector: ^0.1.5
|
visibility_detector: ^0.1.5
|
||||||
http_parser: ^3.1.4
|
|
||||||
meta: ^1.2.4
|
meta: ^1.2.4
|
||||||
lottie: ^0.7.0+1
|
lottie: ^0.7.0+1
|
||||||
substring_highlight: ^0.1.2
|
substring_highlight: ^0.1.2
|
||||||
flutter_slidable: ^0.5.7
|
flutter_slidable: ^0.5.7
|
||||||
clipboard: ^0.1.2+8
|
|
||||||
image_gallery_saver: ^1.6.7
|
image_gallery_saver: ^1.6.7
|
||||||
share_plus: ^1.2.0
|
share_plus: ^1.2.0
|
||||||
photo_manager: ^1.0.0
|
photo_manager: ^1.0.0
|
||||||
transparent_image: ^1.0.0
|
|
||||||
ezanimation: ^0.4.1
|
ezanimation: ^0.4.1
|
||||||
synchronized: ^2.1.0
|
synchronized: ^2.1.0
|
||||||
characters: ^1.0.0
|
characters: ^1.0.0
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 1.5.0
|
||||||
|
|
||||||
|
* Minor fixes and improvements
|
||||||
|
|
||||||
## 1.4.0-beta
|
## 1.4.0-beta
|
||||||
|
|
||||||
* Added `MessageListCore.messageFilter` to filter messages locally
|
* Added `MessageListCore.messageFilter` to filter messages locally
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_flutter_core
|
name: stream_chat_flutter_core
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
|
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
|
||||||
version: 1.4.0-beta
|
version: 1.5.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -10,11 +10,7 @@ environment:
|
|||||||
flutter: ">=1.17.0"
|
flutter: ">=1.17.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
stream_chat:
|
stream_chat: ^1.5.0
|
||||||
git:
|
|
||||||
url: https://github.com/GetStream/stream-chat-flutter.git
|
|
||||||
ref: develop
|
|
||||||
path: packages/stream_chat
|
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
rxdart: ^0.25.0
|
rxdart: ^0.25.0
|
||||||
@@ -24,5 +20,4 @@ dev_dependencies:
|
|||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
fake_async: ^1.1.0
|
fake_async: ^1.1.0
|
||||||
pedantic: ^1.9.2
|
|
||||||
|
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
## 1.5.0
|
||||||
|
|
||||||
|
* Update llc dependency
|
||||||
|
* Wait for all operations to finish before disconnecting
|
||||||
|
|
||||||
## 1.4.0-beta
|
## 1.4.0-beta
|
||||||
|
|
||||||
* Update llc dependency
|
* Update llc dependency
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ linter:
|
|||||||
- avoid_private_typedef_functions
|
- avoid_private_typedef_functions
|
||||||
- avoid_redundant_argument_values
|
- avoid_redundant_argument_values
|
||||||
- avoid_return_types_on_setters
|
- avoid_return_types_on_setters
|
||||||
- avoid_returning_null
|
|
||||||
- avoid_returning_null_for_void
|
- avoid_returning_null_for_void
|
||||||
- avoid_shadowing_type_parameters
|
- avoid_shadowing_type_parameters
|
||||||
- avoid_single_cascade_in_expression_statements
|
- avoid_single_cascade_in_expression_statements
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class Channels extends Table {
|
|||||||
TextColumn get config => text().map(MapConverter<Object>())();
|
TextColumn get config => text().map(MapConverter<Object>())();
|
||||||
|
|
||||||
/// True if this channel entity is frozen
|
/// True if this channel entity is frozen
|
||||||
BoolColumn get frozen => boolean().withDefault(Constant(false))();
|
BoolColumn get frozen => boolean().withDefault(const Constant(false))();
|
||||||
|
|
||||||
/// The date of the last message
|
/// The date of the last message
|
||||||
DateTimeColumn get lastMessageAt => dateTime().nullable()();
|
DateTimeColumn get lastMessageAt => dateTime().nullable()();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_persistence
|
name: stream_chat_persistence
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
|
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
|
||||||
version: 1.4.0-beta
|
version: 1.5.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -11,16 +11,14 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
mutex: ^2.0.0
|
logging: ^0.11.4
|
||||||
|
meta: ^1.2.4
|
||||||
moor: ^3.4.0
|
moor: ^3.4.0
|
||||||
|
mutex: ^2.0.0
|
||||||
path: ^1.7.0
|
path: ^1.7.0
|
||||||
path_provider: ^1.6.27
|
path_provider: ^1.6.27
|
||||||
sqlite3_flutter_libs: ^0.4.0+1
|
sqlite3_flutter_libs: ^0.4.0+1
|
||||||
stream_chat:
|
stream_chat: ^1.5.0
|
||||||
git:
|
|
||||||
url: https://github.com/GetStream/stream-chat-flutter.git
|
|
||||||
ref: develop
|
|
||||||
path: packages/stream_chat
|
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
stream_chat:
|
stream_chat:
|
||||||
|
|||||||
Reference in New Issue
Block a user