Merge branch 'message-input-controller' into feat/unfurl-url-client-side
This commit is contained in:
@@ -305,7 +305,8 @@ class Message extends Equatable {
|
|||||||
quotedMessage != null &&
|
quotedMessage != null &&
|
||||||
quotedMessage is! _NullConst) {
|
quotedMessage is! _NullConst) {
|
||||||
throw ArgumentError(
|
throw ArgumentError(
|
||||||
'`quotedMessage` can only be set as Message or null');
|
'`quotedMessage` can only be set as Message or null',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}(), 'Validate type for quotedMessage');
|
}(), 'Validate type for quotedMessage');
|
||||||
@@ -315,7 +316,8 @@ class Message extends Equatable {
|
|||||||
quotedMessageId != null &&
|
quotedMessageId != null &&
|
||||||
quotedMessageId is! _NullConst) {
|
quotedMessageId is! _NullConst) {
|
||||||
throw ArgumentError(
|
throw ArgumentError(
|
||||||
'`quotedMessage` can only be set as String or null');
|
'`quotedMessage` can only be set as String or null',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}(), 'Validate type for quotedMessage');
|
}(), 'Validate type for quotedMessage');
|
||||||
@@ -412,8 +414,8 @@ class Message extends Equatable {
|
|||||||
shadowed,
|
shadowed,
|
||||||
silent,
|
silent,
|
||||||
command,
|
command,
|
||||||
createdAt,
|
_createdAt,
|
||||||
updatedAt,
|
_updatedAt,
|
||||||
deletedAt,
|
deletedAt,
|
||||||
user,
|
user,
|
||||||
pinned,
|
pinned,
|
||||||
|
|||||||
@@ -756,7 +756,6 @@ void main() {
|
|||||||
const messageId = 'test-message-id';
|
const messageId = 'test-message-id';
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: messageId,
|
id: messageId,
|
||||||
status: MessageSendingStatus.sending,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expectLater(
|
expectLater(
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
## Upcoming
|
## Upcoming
|
||||||
|
|
||||||
|
🛑️ Breaking Changes
|
||||||
|
|
||||||
|
- `MessageInput` now works with a `MessageInputController` instead of a `TextEditingController`
|
||||||
|
|
||||||
|
🐞 Fixed
|
||||||
|
|
||||||
|
- Use file extension instead of mimeType for downloading files
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
🛑️ Breaking Changes from `3.2.0`
|
- Videos can now be auto-played in `FullScreenMedia`
|
||||||
|
|
||||||
- `MessageInput` now works with a `MessageInputController` instead of a `TextEditingController`
|
|
||||||
|
|
||||||
## 3.3.2
|
## 3.3.2
|
||||||
|
|
||||||
|
|||||||
@@ -246,7 +246,8 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
return StreamChannel(
|
return StreamChannel(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
child: FullScreenMedia(
|
child: FullScreenMedia(
|
||||||
mediaAttachments: [attachment],
|
mediaAttachments: message.attachments,
|
||||||
|
startIndex: message.attachments.indexOf(attachment),
|
||||||
userName: message.user?.name,
|
userName: message.user?.name,
|
||||||
message: message,
|
message: message,
|
||||||
onShowMessage: onShowMessage,
|
onShowMessage: onShowMessage,
|
||||||
|
|||||||
@@ -141,7 +141,9 @@ class ImageAttachment extends AttachmentWidget {
|
|||||||
return StreamChannel(
|
return StreamChannel(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
child: FullScreenMedia(
|
child: FullScreenMedia(
|
||||||
mediaAttachments: [attachment],
|
mediaAttachments: message.attachments,
|
||||||
|
startIndex:
|
||||||
|
message.attachments.indexOf(attachment),
|
||||||
userName: message.user?.name,
|
userName: message.user?.name,
|
||||||
message: message,
|
message: message,
|
||||||
onShowMessage: onShowMessage,
|
onShowMessage: onShowMessage,
|
||||||
|
|||||||
@@ -87,7 +87,9 @@ class VideoAttachment extends AttachmentWidget {
|
|||||||
builder: (_) => StreamChannel(
|
builder: (_) => StreamChannel(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
child: FullScreenMedia(
|
child: FullScreenMedia(
|
||||||
mediaAttachments: [attachment],
|
mediaAttachments: message.attachments,
|
||||||
|
startIndex:
|
||||||
|
message.attachments.indexOf(attachment),
|
||||||
userName: message.user?.name,
|
userName: message.user?.name,
|
||||||
message: message,
|
message: message,
|
||||||
onShowMessage: onShowMessage,
|
onShowMessage: onShowMessage,
|
||||||
|
|||||||
@@ -365,12 +365,13 @@ class AttachmentActionsModal extends StatelessWidget {
|
|||||||
}) async {
|
}) async {
|
||||||
String? filePath;
|
String? filePath;
|
||||||
final appDocDir = await getTemporaryDirectory();
|
final appDocDir = await getTemporaryDirectory();
|
||||||
|
final url =
|
||||||
|
attachment.assetUrl ?? attachment.imageUrl ?? attachment.thumbUrl!;
|
||||||
await Dio().download(
|
await Dio().download(
|
||||||
attachment.assetUrl ?? attachment.imageUrl ?? attachment.thumbUrl!,
|
url,
|
||||||
(Headers responseHeaders) {
|
(Headers responseHeaders) {
|
||||||
final contentType = responseHeaders[Headers.contentTypeHeader]!;
|
final ext = Uri.parse(url).pathSegments.last;
|
||||||
final mimeType = contentType.first.split('/').last;
|
filePath ??= '${appDocDir.path}/${attachment.id}.$ext';
|
||||||
filePath ??= '${appDocDir.path}/${attachment.id}.$mimeType';
|
|
||||||
return filePath!;
|
return filePath!;
|
||||||
},
|
},
|
||||||
onReceiveProgress: progressCallback,
|
onReceiveProgress: progressCallback,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class FullScreenMedia extends StatefulWidget {
|
|||||||
String? userName,
|
String? userName,
|
||||||
this.onShowMessage,
|
this.onShowMessage,
|
||||||
this.attachmentActionsModalBuilder,
|
this.attachmentActionsModalBuilder,
|
||||||
|
this.autoplayVideos = false,
|
||||||
}) : userName = userName ?? '',
|
}) : userName = userName ?? '',
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
@@ -57,6 +58,9 @@ class FullScreenMedia extends StatefulWidget {
|
|||||||
/// Use [defaultActionsModal.copyWith] to easily customize it
|
/// Use [defaultActionsModal.copyWith] to easily customize it
|
||||||
final AttachmentActionsBuilder? attachmentActionsModalBuilder;
|
final AttachmentActionsBuilder? attachmentActionsModalBuilder;
|
||||||
|
|
||||||
|
/// Auto-play videos when page is opened
|
||||||
|
final bool autoplayVideos;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_FullScreenMediaState createState() => _FullScreenMediaState();
|
_FullScreenMediaState createState() => _FullScreenMediaState();
|
||||||
}
|
}
|
||||||
@@ -81,7 +85,8 @@ class _FullScreenMediaState extends State<FullScreenMedia>
|
|||||||
);
|
);
|
||||||
_pageController = PageController(initialPage: widget.startIndex);
|
_pageController = PageController(initialPage: widget.startIndex);
|
||||||
_currentPage = widget.startIndex;
|
_currentPage = widget.startIndex;
|
||||||
for (final attachment in widget.mediaAttachments) {
|
for (var i = 0; i < widget.mediaAttachments.length; i++) {
|
||||||
|
final attachment = widget.mediaAttachments[i];
|
||||||
if (attachment.type != 'video') continue;
|
if (attachment.type != 'video') continue;
|
||||||
final package = VideoPackage(attachment, showControls: true);
|
final package = VideoPackage(attachment, showControls: true);
|
||||||
videoPackages[attachment.id] = package;
|
videoPackages[attachment.id] = package;
|
||||||
@@ -90,9 +95,21 @@ class _FullScreenMediaState extends State<FullScreenMedia>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initializePlayers() async {
|
Future<void> initializePlayers() async {
|
||||||
|
if (videoPackages.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final currentAttachment = widget.mediaAttachments[widget.startIndex];
|
||||||
|
|
||||||
await Future.wait(videoPackages.values.map(
|
await Future.wait(videoPackages.values.map(
|
||||||
(it) => it.initialize(),
|
(it) => it.initialize(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if (widget.autoplayVideos && currentAttachment.type == 'video') {
|
||||||
|
final package = videoPackages.values
|
||||||
|
.firstWhere((e) => e._attachment == currentAttachment);
|
||||||
|
package._chewieController?.play();
|
||||||
|
}
|
||||||
setState(() {}); // ignore: no-empty-block
|
setState(() {}); // ignore: no-empty-block
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,6 +126,24 @@ class _FullScreenMediaState extends State<FullScreenMedia>
|
|||||||
setState(() {
|
setState(() {
|
||||||
_currentPage = val;
|
_currentPage = val;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (videoPackages.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final currentAttachment = widget.mediaAttachments[val];
|
||||||
|
|
||||||
|
for (final e in videoPackages.values) {
|
||||||
|
if (e._attachment != currentAttachment) {
|
||||||
|
e._chewieController?.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widget.autoplayVideos &&
|
||||||
|
currentAttachment.type == 'video') {
|
||||||
|
final controller = videoPackages[currentAttachment.id]!;
|
||||||
|
controller._chewieController?.play();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final attachment = widget.mediaAttachments[index];
|
final attachment = widget.mediaAttachments[index];
|
||||||
@@ -243,15 +278,16 @@ class _FullScreenMediaState extends State<FullScreenMedia>
|
|||||||
class VideoPackage {
|
class VideoPackage {
|
||||||
/// Constructor for creating [VideoPackage]
|
/// Constructor for creating [VideoPackage]
|
||||||
VideoPackage(
|
VideoPackage(
|
||||||
Attachment attachment, {
|
this._attachment, {
|
||||||
bool showControls = false,
|
bool showControls = false,
|
||||||
bool autoInitialize = true,
|
bool autoInitialize = true,
|
||||||
}) : _showControls = showControls,
|
}) : _showControls = showControls,
|
||||||
_autoInitialize = autoInitialize,
|
_autoInitialize = autoInitialize,
|
||||||
_videoPlayerController = attachment.localUri != null
|
_videoPlayerController = _attachment.localUri != null
|
||||||
? VideoPlayerController.file(File.fromUri(attachment.localUri!))
|
? VideoPlayerController.file(File.fromUri(_attachment.localUri!))
|
||||||
: VideoPlayerController.network(attachment.assetUrl!);
|
: VideoPlayerController.network(_attachment.assetUrl!);
|
||||||
|
|
||||||
|
final Attachment _attachment;
|
||||||
final bool _showControls;
|
final bool _showControls;
|
||||||
final bool _autoInitialize;
|
final bool _autoInitialize;
|
||||||
final VideoPlayerController _videoPlayerController;
|
final VideoPlayerController _videoPlayerController;
|
||||||
|
|||||||
@@ -23,41 +23,8 @@ typedef CustomAttachmentIconBuilder = Widget Function(
|
|||||||
|
|
||||||
/// A widget that allows to pick an attachment.
|
/// A widget that allows to pick an attachment.
|
||||||
class StreamAttachmentPicker extends StatefulWidget {
|
class StreamAttachmentPicker extends StatefulWidget {
|
||||||
/// True if the picker is open.
|
/// Default constructor for [StreamAttachmentPicker] which creates the Stream
|
||||||
final bool isOpen;
|
/// attachment picker widget.
|
||||||
|
|
||||||
/// The picker size in height.
|
|
||||||
final double pickerSize;
|
|
||||||
|
|
||||||
/// The [MessageInputController] linked to this picker.
|
|
||||||
final MessageInputController messageInputController;
|
|
||||||
|
|
||||||
/// The limit of attachments that can be picked.
|
|
||||||
final int attachmentLimit;
|
|
||||||
|
|
||||||
/// The callback for when the attachment limit is exceeded.
|
|
||||||
final AttachmentLimitExceedListener? onAttachmentLimitExceeded;
|
|
||||||
|
|
||||||
final ValueChanged<String>? onError;
|
|
||||||
final FilePickerCallback onFilePicked;
|
|
||||||
|
|
||||||
/// Video quality to use when compressing the videos.
|
|
||||||
final VideoQuality compressedVideoQuality;
|
|
||||||
|
|
||||||
/// Frame rate to use when compressing the videos.
|
|
||||||
final int compressedVideoFrameRate;
|
|
||||||
|
|
||||||
/// Max attachment size in bytes:
|
|
||||||
/// - Defaults to 20 MB
|
|
||||||
/// - Do not set it if you're using our default CDN
|
|
||||||
final int maxAttachmentSize;
|
|
||||||
|
|
||||||
/// The list of attachment types that can be picked.
|
|
||||||
final List<DefaultAttachmentTypes> allowedAttachmentTypes;
|
|
||||||
|
|
||||||
/// The list of custom attachment types that can be picked.
|
|
||||||
final List<CustomAttachmentType> customAttachmentTypes;
|
|
||||||
|
|
||||||
const StreamAttachmentPicker({
|
const StreamAttachmentPicker({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.messageInputController,
|
required this.messageInputController,
|
||||||
@@ -78,6 +45,46 @@ class StreamAttachmentPicker extends StatefulWidget {
|
|||||||
this.customAttachmentTypes = const [],
|
this.customAttachmentTypes = const [],
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
/// True if the picker is open.
|
||||||
|
final bool isOpen;
|
||||||
|
|
||||||
|
/// The picker size in height.
|
||||||
|
final double pickerSize;
|
||||||
|
|
||||||
|
/// The [MessageInputController] linked to this picker.
|
||||||
|
final MessageInputController messageInputController;
|
||||||
|
|
||||||
|
/// The limit of attachments that can be picked.
|
||||||
|
final int attachmentLimit;
|
||||||
|
|
||||||
|
/// The callback for when the attachment limit is exceeded.
|
||||||
|
final AttachmentLimitExceedListener? onAttachmentLimitExceeded;
|
||||||
|
|
||||||
|
/// Callback for when an error occurs in the attachment picker.
|
||||||
|
final ValueChanged<String>? onError;
|
||||||
|
|
||||||
|
/// Callback for when file is picked.
|
||||||
|
final FilePickerCallback onFilePicked;
|
||||||
|
|
||||||
|
/// Video quality to use when compressing the videos.
|
||||||
|
final VideoQuality compressedVideoQuality;
|
||||||
|
|
||||||
|
/// Frame rate to use when compressing the videos.
|
||||||
|
final int compressedVideoFrameRate;
|
||||||
|
|
||||||
|
/// Max attachment size in bytes:
|
||||||
|
/// - Defaults to 20 MB
|
||||||
|
/// - Do not set it if you're using our default CDN
|
||||||
|
final int maxAttachmentSize;
|
||||||
|
|
||||||
|
/// The list of attachment types that can be picked.
|
||||||
|
final List<DefaultAttachmentTypes> allowedAttachmentTypes;
|
||||||
|
|
||||||
|
/// The list of custom attachment types that can be picked.
|
||||||
|
final List<CustomAttachmentType> customAttachmentTypes;
|
||||||
|
|
||||||
|
/// Used to create a new copy of [StreamAttachmentPicker] with modified
|
||||||
|
/// properties.
|
||||||
StreamAttachmentPicker copyWith({
|
StreamAttachmentPicker copyWith({
|
||||||
Key? key,
|
Key? key,
|
||||||
MessageInputController? messageInputController,
|
MessageInputController? messageInputController,
|
||||||
@@ -334,8 +341,8 @@ class _StreamAttachmentPickerState extends State<StreamAttachmentPicker> {
|
|||||||
onMediaSelected: (media) {
|
onMediaSelected: (media) {
|
||||||
if (messageInputController.attachments
|
if (messageInputController.attachments
|
||||||
.any((e) => e.id == media.id)) {
|
.any((e) => e.id == media.id)) {
|
||||||
setState(() => messageInputController.attachments
|
messageInputController
|
||||||
.removeWhere((e) => e.id == media.id));
|
.removeAttachmentById(media.id);
|
||||||
} else {
|
} else {
|
||||||
_addAssetAttachment(media);
|
_addAssetAttachment(media);
|
||||||
}
|
}
|
||||||
@@ -547,14 +554,22 @@ class _PickerWidgetState extends State<_PickerWidget> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Class which holds data for a custom attachment type in the attachment picker
|
||||||
class CustomAttachmentType {
|
class CustomAttachmentType {
|
||||||
String type;
|
/// Default constructor for creating a custom attachment for the attachment
|
||||||
CustomAttachmentIconBuilder iconBuilder;
|
/// picker.
|
||||||
WidgetBuilder pickerBuilder;
|
|
||||||
|
|
||||||
CustomAttachmentType({
|
CustomAttachmentType({
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.iconBuilder,
|
required this.iconBuilder,
|
||||||
required this.pickerBuilder,
|
required this.pickerBuilder,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Type name.
|
||||||
|
String type;
|
||||||
|
|
||||||
|
/// Builds the icon in the attachment picker top row.
|
||||||
|
CustomAttachmentIconBuilder iconBuilder;
|
||||||
|
|
||||||
|
/// Builds content in the attachment builder when icon is selected.
|
||||||
|
WidgetBuilder pickerBuilder;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// ignore_for_file: prefer-trailing-comma, cascade_invocations
|
// ignore_for_file: prefer-trailing-comma, cascade_invocations, lines_longer_than_80_chars
|
||||||
|
|
||||||
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
|
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
|
||||||
|
|
||||||
@@ -44,7 +44,8 @@ class StreamMessageTextField extends StatefulWidget {
|
|||||||
/// After [maxLength] characters have been input, additional input
|
/// After [maxLength] characters have been input, additional input
|
||||||
/// is ignored, unless [maxLengthEnforcement] is set to
|
/// is ignored, unless [maxLengthEnforcement] is set to
|
||||||
/// [MaxLengthEnforcement.none].
|
/// [MaxLengthEnforcement.none].
|
||||||
/// The text field enforces the length with a [LengthLimitingTextInputFormatter],
|
/// The text field enforces the length with a
|
||||||
|
/// [LengthLimitingTextInputFormatter],
|
||||||
/// which is evaluated after the supplied [inputFormatters], if any.
|
/// which is evaluated after the supplied [inputFormatters], if any.
|
||||||
/// The [maxLength] value must be either null or greater than zero.
|
/// The [maxLength] value must be either null or greater than zero.
|
||||||
///
|
///
|
||||||
@@ -633,7 +634,7 @@ class StreamMessageTextField extends StatefulWidget {
|
|||||||
defaultValue: null));
|
defaultValue: null));
|
||||||
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>(
|
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>(
|
||||||
'scrollPadding', scrollPadding,
|
'scrollPadding', scrollPadding,
|
||||||
defaultValue: const EdgeInsets.all(20.0)));
|
defaultValue: const EdgeInsets.all(20)));
|
||||||
properties.add(FlagProperty('selectionEnabled',
|
properties.add(FlagProperty('selectionEnabled',
|
||||||
value: selectionEnabled,
|
value: selectionEnabled,
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
@@ -702,7 +703,6 @@ class _StreamMessageTextFieldState extends State<StreamMessageTextField>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => TextField(
|
Widget build(BuildContext context) => TextField(
|
||||||
key: widget.key,
|
|
||||||
controller: _effectiveController.textEditingController,
|
controller: _effectiveController.textEditingController,
|
||||||
onChanged: (newText) {
|
onChanged: (newText) {
|
||||||
_effectiveController.text = newText;
|
_effectiveController.text = newText;
|
||||||
|
|||||||
@@ -23,16 +23,16 @@ export 'src/localization/stream_chat_localizations.dart';
|
|||||||
export 'src/localization/translations.dart' show DefaultTranslations;
|
export 'src/localization/translations.dart' show DefaultTranslations;
|
||||||
export 'src/mention_tile.dart';
|
export 'src/mention_tile.dart';
|
||||||
export 'src/message_action.dart';
|
export 'src/message_action.dart';
|
||||||
|
export 'src/message_input/countdown_button.dart';
|
||||||
export 'src/message_input/message_input.dart';
|
export 'src/message_input/message_input.dart';
|
||||||
|
export 'src/message_input/stream_attachment_picker.dart';
|
||||||
|
export 'src/message_input/stream_message_send_button.dart';
|
||||||
|
export 'src/message_input/stream_message_text_field.dart';
|
||||||
export 'src/message_list_view.dart';
|
export 'src/message_list_view.dart';
|
||||||
export 'src/message_search_item.dart';
|
export 'src/message_search_item.dart';
|
||||||
export 'src/message_search_list_view.dart';
|
export 'src/message_search_list_view.dart';
|
||||||
export 'src/message_text.dart';
|
export 'src/message_text.dart';
|
||||||
export 'src/message_widget.dart';
|
export 'src/message_widget.dart';
|
||||||
export 'src/message_input/countdown_button.dart';
|
|
||||||
export 'src/message_input/stream_attachment_picker.dart';
|
|
||||||
export 'src/message_input/stream_message_send_button.dart';
|
|
||||||
export 'src/message_input/stream_message_text_field.dart';
|
|
||||||
export 'src/option_list_tile.dart';
|
export 'src/option_list_tile.dart';
|
||||||
export 'src/reaction_icon.dart';
|
export 'src/reaction_icon.dart';
|
||||||
export 'src/reaction_picker.dart';
|
export 'src/reaction_picker.dart';
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
import 'package:stream_chat_flutter/src/attachment_actions_modal.dart';
|
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
|
||||||
import 'mocks.dart';
|
import 'mocks.dart';
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
import 'package:stream_chat_flutter/src/message_actions_modal.dart';
|
import 'package:stream_chat_flutter/src/message_actions_modal.dart';
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
|
|
||||||
import 'mocks.dart';
|
import 'mocks.dart';
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ void main() {
|
|||||||
user: User(
|
user: User(
|
||||||
id: 'user-id',
|
id: 'user-id',
|
||||||
),
|
),
|
||||||
|
status: MessageSendingStatus.sent,
|
||||||
),
|
),
|
||||||
messageWidget: const Text(
|
messageWidget: const Text(
|
||||||
'test',
|
'test',
|
||||||
@@ -196,6 +198,7 @@ void main() {
|
|||||||
user: User(
|
user: User(
|
||||||
id: 'user-id',
|
id: 'user-id',
|
||||||
),
|
),
|
||||||
|
status: MessageSendingStatus.sent,
|
||||||
),
|
),
|
||||||
messageTheme: streamTheme.ownMessageTheme,
|
messageTheme: streamTheme.ownMessageTheme,
|
||||||
),
|
),
|
||||||
@@ -242,6 +245,7 @@ void main() {
|
|||||||
user: User(
|
user: User(
|
||||||
id: 'user-id',
|
id: 'user-id',
|
||||||
),
|
),
|
||||||
|
status: MessageSendingStatus.sent,
|
||||||
),
|
),
|
||||||
messageTheme: streamTheme.ownMessageTheme,
|
messageTheme: streamTheme.ownMessageTheme,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user