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:
Sahil Kumar
2021-03-19 18:26:31 +05:30
26 changed files with 263 additions and 159 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
repo: GetStream/flutter-samples
token: ${{ secrets.GH_TOKEN }}
dispatch_stable:
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: benc-uk/workflow-dispatch@v1
+2
View File
@@ -5,6 +5,8 @@ on:
- opened
- edited
- synchronize
branches:
- develop
jobs:
main:
@@ -8,12 +8,12 @@ on:
push:
branches:
- master
- develop
paths-ignore:
- 'docs/**'
jobs:
analyze:
if: github.base_ref == 'master'
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
+5
View File
@@ -20,6 +20,11 @@ Stream allows developers to rapidly deploy scalable feeds and chat messaging wit
## 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).
## 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
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`.
+4
View File
@@ -1,3 +1,7 @@
## 1.5.0
- Minor fixes and improvements
## 1.4.0-beta
- Improved attachment uploading
@@ -44,7 +44,6 @@ linter:
- 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
@@ -1209,6 +1209,7 @@ class ChannelClientState {
ChannelClientState(
this._channel,
ChannelState channelState,
//ignore: unnecessary_parenthesis
) : _debouncedUpdatePersistenceChannelState = ((ChannelState state) {
_channel?._client?.chatPersistenceClient?.updateChannelState(state);
}).debounced(const Duration(seconds: 1)) {
+1 -1
View File
@@ -3,4 +3,4 @@ import 'package:stream_chat/src/client.dart';
/// Current package version
/// Used in [StreamChatClient] to build the `x-stream-client` header
// ignore: constant_identifier_names
const PACKAGE_VERSION = '1.4.0-beta';
const PACKAGE_VERSION = '1.5.0';
+1 -1
View File
@@ -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.4.0-beta
version: 1.5.0
repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
+13 -1
View File
@@ -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
- Unfocus `MessageInput` only when sending commands
@@ -10,7 +22,7 @@
- Added `MessageListView.onAttachmentTap` callback
- Fixed message newline issue
- Fixed `MessageListView` scroll keyboard behaviour
- Minor fixes and improveqments
- Minor fixes and improvements
## 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/video_thumbnail_image.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 'attachment_widget.dart';
@@ -1,10 +1,7 @@
import 'dart:typed_data';
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 'package:transparent_image/transparent_image.dart';
import '../full_screen_media.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_core/stream_chat_flutter_core.dart';
import 'attachment_title.dart';
import '../full_screen_media.dart';
import '../stream_chat_theme.dart';
import 'attachment_title.dart';
import 'attachment_widget.dart';
class ImageAttachment extends AttachmentWidget {
@@ -81,6 +81,7 @@ class ImageAttachment extends AttachmentWidget {
return _buildImageAttachment(
context,
CachedNetworkImage(
cacheKey: imageUri.path,
height: size?.height,
width: size?.width,
placeholder: (_, __) {
@@ -5,10 +5,10 @@ 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';
import 'package:stream_chat_flutter/src/utils.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'extension.dart';
import 'message_input.dart';
@@ -34,6 +34,7 @@ class MessageActionsModal extends StatefulWidget {
final ShapeBorder messageShape;
final ShapeBorder attachmentShape;
final DisplayWidget showUserAvatar;
final BorderRadius attachmentBorderRadiusGeometry;
/// List of custom actions
final List<MessageAction> customActions;
@@ -58,6 +59,7 @@ class MessageActionsModal extends StatefulWidget {
this.attachmentShape,
this.reverse = false,
this.customActions = const [],
this.attachmentBorderRadiusGeometry,
}) : super(key: key);
@override
@@ -153,6 +155,8 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
child: MessageWidget(
key: Key('MessageWidget'),
reverse: widget.reverse,
attachmentBorderRadiusGeometry:
widget.attachmentBorderRadiusGeometry,
message: widget.message.copyWith(
text: widget.message.text.length > 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: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';
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/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:substring_highlight/substring_highlight.dart';
@@ -35,6 +35,8 @@ typedef AttachmentThumbnailBuilder = Widget Function(
enum ActionsLocation {
left,
right,
leftInside,
rightInside,
}
enum DefaultAttachmentTypes {
@@ -122,6 +124,7 @@ class MessageInput extends StatefulWidget {
this.hideSendAsDm = false,
this.idleSendButton,
this.activeSendButton,
this.showCommandsButton = true,
}) : super(key: key);
/// Message to edit
@@ -149,6 +152,9 @@ class MessageInput extends StatefulWidget {
/// If true the attachments button will not be displayed
final bool disableAttachments;
/// Use this property to hide/show the commands button
final bool showCommandsButton;
/// Hide send as dm checkbox
final bool hideSendAsDm;
@@ -308,7 +314,7 @@ class MessageInputState extends State<MessageInput> {
),
),
Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: _buildTextField(context),
),
if (widget.parentMessage != null && !widget.hideSendAsDm)
@@ -336,12 +342,11 @@ class MessageInputState extends State<MessageInput> {
direction: Axis.horizontal,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
if (!_commandEnabled) _buildExpandActionsButton(),
if (widget.actionsLocation == ActionsLocation.left)
...widget.actions ?? [],
if (!_commandEnabled && widget.actionsLocation == ActionsLocation.left)
_buildExpandActionsButton(),
_buildTextInput(context),
if (widget.actionsLocation == ActionsLocation.right)
...widget.actions ?? [],
if (!_commandEnabled && widget.actionsLocation == ActionsLocation.right)
_buildExpandActionsButton(),
if (widget.sendButtonLocation == SendButtonLocation.outside)
_animateSendButton(context),
],
@@ -421,32 +426,36 @@ class MessageInputState extends State<MessageInput> {
child: widget.activeSendButton,
)
: _buildSendButton(context);
return Padding(
padding: const EdgeInsets.all(8.0),
child: AnimatedCrossFade(
crossFadeState: (_messageIsPresent || _attachments.isNotEmpty)
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
firstChild: sendButton,
secondChild: widget.idleSendButton ?? _buildIdleSendButton(context),
duration:
StreamChatTheme.of(context).messageInputTheme.sendAnimationDuration,
alignment: Alignment.center,
),
return AnimatedCrossFade(
crossFadeState: (_messageIsPresent || _attachments.isNotEmpty)
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
firstChild: sendButton,
secondChild: widget.idleSendButton ?? _buildIdleSendButton(context),
duration:
StreamChatTheme.of(context).messageInputTheme.sendAnimationDuration,
alignment: Alignment.center,
);
}
Widget _buildExpandActionsButton() {
return Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: AnimatedCrossFade(
crossFadeState: _actionsShrunk
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
firstChild: IconButton(
onPressed: () => setState(() => _actionsShrunk = false),
icon: StreamSvgIcon.emptyCircleLeft(
color: StreamChatTheme.of(context).colorTheme.accentBlue,
icon: Transform.rotate(
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),
constraints: BoxConstraints.tightFor(
@@ -457,10 +466,12 @@ class MessageInputState extends State<MessageInput> {
),
secondChild: FittedBox(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
children: <Widget>[
if (!widget.disableAttachments) _buildAttachmentButton(),
if (widget.editMessage == null &&
if (widget.showCommandsButton &&
widget.editMessage == null &&
StreamChannel.of(context)
.channel
?.config
@@ -468,6 +479,7 @@ class MessageInputState extends State<MessageInput> {
?.isNotEmpty ==
true)
_buildCommandButton(),
...widget.actions ?? [],
].insertBetween(const SizedBox(width: 8)),
),
),
@@ -565,51 +577,75 @@ class MessageInputState extends State<MessageInput> {
),
),
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(
? Row(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
constraints: BoxConstraints.tight(Size(64, 24)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: theme.colorTheme.accentBlue,
),
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,
: (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(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (_commandEnabled)
IconButton(
icon: StreamSvgIcon.closeSmall(),
splashRadius: 24,
padding: const EdgeInsets.all(0),
constraints: BoxConstraints.tightFor(
height: 24,
width: 24,
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: IconButton(
icon: StreamSvgIcon.closeSmall(),
splashRadius: 24,
padding: const EdgeInsets.all(0),
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)
_animateSendButton(context),
],
@@ -619,7 +655,13 @@ class MessageInputState extends State<MessageInput> {
Timer _debounce;
String _previousValue;
void _onChanged(BuildContext context, String s) {
if (s == _previousValue) {
return;
}
_previousValue = s;
if (_debounce?.isActive == true) _debounce.cancel();
_debounce = Timer(
const Duration(milliseconds: 350),
@@ -631,7 +673,11 @@ class MessageInputState extends State<MessageInput> {
setState(() {
_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();
@@ -1684,13 +1730,19 @@ class MessageInputState extends State<MessageInput> {
}
Widget _buildCommandButton() {
final s = textEditingController.text.trim();
return IconButton(
icon: StreamSvgIcon.lightning(
color: _commandsOverlay != null
? StreamChatTheme.of(context).messageInputTheme.actionButtonColor
: StreamChatTheme.of(context)
.messageInputTheme
.actionButtonIdleColor,
color: s.isNotEmpty
? StreamChatTheme.of(context).colorTheme.greyGainsboro
: (_commandsOverlay != null
? StreamChatTheme.of(context)
.messageInputTheme
.actionButtonColor
: StreamChatTheme.of(context)
.messageInputTheme
.actionButtonIdleColor),
),
padding: const EdgeInsets.all(0),
constraints: BoxConstraints.tightFor(
@@ -1711,7 +1763,9 @@ class MessageInputState extends State<MessageInput> {
if (_commandsOverlay == null) {
setState(() {
_commandsOverlay = _buildCommandsOverlayEntry();
Overlay.of(context).insert(_commandsOverlay);
if (_commandsOverlay != null) {
Overlay.of(context).insert(_commandsOverlay);
}
});
} else {
setState(() {
@@ -1904,11 +1958,11 @@ class MessageInputState extends State<MessageInput> {
if (file == null) return;
final mimeType = file.name?.mimeType;
final mimeType = file.name?.mimeType ?? file.path.split('/').last.mimeType;
final extraDataMap = <String, dynamic>{};
if (mimeType.type == 'video' || mimeType.type == 'image') {
if (mimeType?.type == 'video' || mimeType?.type == 'image') {
attachmentType = mimeType.type;
} else {
attachmentType = 'file';
@@ -1965,24 +2019,31 @@ class MessageInputState extends State<MessageInput> {
}
Widget _buildIdleSendButton(BuildContext context) {
return StreamSvgIcon(
assetName: _getIdleSendIcon(),
color: StreamChatTheme.of(context).messageInputTheme.sendButtonIdleColor,
return Padding(
padding: const EdgeInsets.all(8.0),
child: StreamSvgIcon(
assetName: _getIdleSendIcon(),
color:
StreamChatTheme.of(context).messageInputTheme.sendButtonIdleColor,
),
);
}
Widget _buildSendButton(BuildContext context) {
return IconButton(
onPressed: sendMessage,
padding: const EdgeInsets.all(0),
splashRadius: 24,
constraints: BoxConstraints.tightFor(
height: 24,
width: 24,
),
icon: StreamSvgIcon(
assetName: _getSendIcon(),
color: StreamChatTheme.of(context).messageInputTheme.sendButtonColor,
return Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
onPressed: sendMessage,
padding: const EdgeInsets.all(0),
splashRadius: 24,
constraints: BoxConstraints.tightFor(
height: 24,
width: 24,
),
icon: StreamSvgIcon(
assetName: _getSendIcon(),
color: StreamChatTheme.of(context).messageInputTheme.sendButtonColor,
),
),
);
}
@@ -749,7 +749,7 @@ class _MessageListViewState extends State<MessageListView> {
Widget messageWidget;
if (widget.messageBuilder != null) {
messageWidget = Builder(
key: ValueKey<String>('BOTTOM-MESSAGE'),
key: ValueKey<String>('BOTTOM-MESSAGE-${message.id}'),
builder: (_) => widget.messageBuilder(
context,
MessageDetails(
@@ -766,7 +766,7 @@ class _MessageListViewState extends State<MessageListView> {
}
return VisibilityDetector(
key: ValueKey<String>('BOTTOM-MESSAGE'),
key: ValueKey<String>('BOTTOM-MESSAGE-${message.id}'),
onVisibilityChanged: (visibility) {
final isVisible = visibility.visibleBounds != Rect.zero;
if (isVisible) {
@@ -1021,15 +1021,19 @@ class _MessageListViewState extends State<MessageListView> {
!message.isSystem &&
!message.isEphemeral &&
widget.onMessageSwiped != null) {
child = Swipeable(
onSwipeEnd: () {
FocusScope.of(context).unfocus();
widget.onMessageSwiped(message);
},
backgroundIcon: StreamSvgIcon.reply(
color: StreamChatTheme.of(context).colorTheme.accentBlue,
child = Container(
decoration: BoxDecoration(),
clipBehavior: Clip.hardEdge,
child: Swipeable(
onSwipeEnd: () {
FocusScope.of(context).unfocus();
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 '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_picker.dart';
import 'package:stream_chat_flutter/src/stream_chat.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 'stream_chat_theme.dart';
import 'extension.dart';
class MessageReactionsModal extends StatelessWidget {
final Widget Function(BuildContext, Message) editMessageInputBuilder;
@@ -24,6 +23,7 @@ class MessageReactionsModal extends StatelessWidget {
final ShapeBorder messageShape;
final ShapeBorder attachmentShape;
final void Function(User) onUserAvatarTap;
final BorderRadius attachmentBorderRadiusGeometry;
const MessageReactionsModal({
Key key,
@@ -37,6 +37,7 @@ class MessageReactionsModal extends StatelessWidget {
this.reverse = false,
this.showUserAvatar = DisplayWidget.show,
this.onUserAvatarTap,
this.attachmentBorderRadiusGeometry,
}) : super(key: key);
@override
@@ -133,6 +134,8 @@ class MessageReactionsModal extends StatelessWidget {
shape: messageShape,
attachmentShape: attachmentShape,
padding: const EdgeInsets.all(0),
attachmentBorderRadiusGeometry:
attachmentBorderRadiusGeometry,
attachmentPadding: EdgeInsets.all(
hasFileAttachment ? 4 : 2,
),
@@ -235,6 +235,7 @@ class MessageWidget extends StatefulWidget {
),
border,
reverse,
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
),
);
}
@@ -259,6 +260,7 @@ class MessageWidget extends StatefulWidget {
),
border,
reverse,
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
);
},
'video': (context, message, attachments) {
@@ -291,6 +293,7 @@ class MessageWidget extends StatefulWidget {
),
border,
reverse,
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
);
},
'giphy': (context, message, attachments) {
@@ -318,6 +321,7 @@ class MessageWidget extends StatefulWidget {
),
border,
reverse,
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
);
},
'file': (context, message, attachments) {
@@ -329,22 +333,28 @@ class MessageWidget extends StatefulWidget {
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
);
return wrapAttachmentWidget(
context,
Column(
children: attachments.map((attachment) {
return FileAttachment(
message: message,
attachment: attachment,
size: Size(
MediaQuery.of(context).size.width * 0.8,
MediaQuery.of(context).size.height * 0.3,
),
);
}).toList(),
),
border,
reverse,
return Column(
children: attachments
.map<Widget>((attachment) {
return wrapAttachmentWidget(
context,
FileAttachment(
message: message,
attachment: attachment,
size: Size(
MediaQuery.of(context).size.width * 0.8,
MediaQuery.of(context).size.height * 0.3,
),
),
border,
reverse,
attachmentBorderRadiusGeometry ?? BorderRadius.zero,
);
})
.insertBetween(SizedBox(
height: attachmentPadding.vertical / 2,
))
.toList(),
);
},
}..addAll(customAttachmentBuilders ?? {}),
@@ -822,6 +832,8 @@ class _MessageWidgetState extends State<MessageWidget>
return StreamChannel(
channel: channel,
child: MessageActionsModal(
attachmentBorderRadiusGeometry:
widget.attachmentBorderRadiusGeometry,
showUserAvatar:
widget.message.user.id == channel.client.state.user.id
? DisplayWidget.gone
@@ -869,6 +881,8 @@ class _MessageWidgetState extends State<MessageWidget>
return StreamChannel(
channel: channel,
child: MessageReactionsModal(
attachmentBorderRadiusGeometry:
widget.attachmentBorderRadiusGeometry,
showUserAvatar:
widget.message.user.id == channel.client.state.user.id
? DisplayWidget.gone
@@ -913,7 +927,7 @@ class _MessageWidgetState extends State<MessageWidget>
}
Widget _parseAttachments() {
Map<String, List<Attachment>> attachmentGroups = {};
final attachmentGroups = <String, List<Attachment>>{};
widget.message.attachments
.where((element) => element.ogScrapeUrl == null)
@@ -925,7 +939,7 @@ class _MessageWidgetState extends State<MessageWidget>
attachmentGroups[e.type].add(e);
});
List<Widget> attachmentList = [];
final attachmentList = <Widget>[];
attachmentGroups.forEach((type, attachments) {
final attachmentBuilder = widget.attachmentBuilders[type];
@@ -356,15 +356,19 @@ Widget wrapAttachmentWidget(
Widget attachmentWidget,
ShapeBorder attachmentShape,
bool reverse,
BorderRadius borderRadius,
) {
return Material(
clipBehavior: Clip.antiAlias,
shape: attachmentShape,
type: MaterialType.transparency,
child: Transform(
transform: Matrix4.rotationY(reverse ? pi : 0),
alignment: Alignment.center,
child: attachmentWidget,
return ClipRRect(
borderRadius: borderRadius,
child: Material(
clipBehavior: Clip.antiAlias,
shape: attachmentShape,
type: MaterialType.transparency,
child: Transform(
transform: Matrix4.rotationY(reverse ? pi : 0),
alignment: Alignment.center,
child: attachmentWidget,
),
),
);
}
+2 -9
View File
@@ -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.4.0-beta
version: 1.5.1
repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
@@ -11,11 +11,7 @@ environment:
dependencies:
flutter:
sdk: flutter
stream_chat_flutter_core:
git:
url: https://github.com/GetStream/stream-chat-flutter.git
ref: develop
path: packages/stream_chat_flutter_core
stream_chat_flutter_core: ^1.5.0
photo_view: ^0.11.0
rxdart: ^0.25.0
scrollable_positioned_list: ^0.1.8
@@ -34,16 +30,13 @@ dependencies:
flutter_keyboard_visibility: ^4.0.2
video_compress: ^2.1.1
visibility_detector: ^0.1.5
http_parser: ^3.1.4
meta: ^1.2.4
lottie: ^0.7.0+1
substring_highlight: ^0.1.2
flutter_slidable: ^0.5.7
clipboard: ^0.1.2+8
image_gallery_saver: ^1.6.7
share_plus: ^1.2.0
photo_manager: ^1.0.0
transparent_image: ^1.0.0
ezanimation: ^0.4.1
synchronized: ^2.1.0
characters: ^1.0.0
@@ -1,3 +1,7 @@
## 1.5.0
* Minor fixes and improvements
## 1.4.0-beta
* Added `MessageListCore.messageFilter` to filter messages locally
@@ -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.4.0-beta
version: 1.5.0
repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
@@ -10,11 +10,7 @@ environment:
flutter: ">=1.17.0"
dependencies:
stream_chat:
git:
url: https://github.com/GetStream/stream-chat-flutter.git
ref: develop
path: packages/stream_chat
stream_chat: ^1.5.0
flutter:
sdk: flutter
rxdart: ^0.25.0
@@ -24,5 +20,4 @@ dev_dependencies:
flutter_test:
sdk: flutter
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
* Update llc dependency
@@ -44,7 +44,6 @@ linter:
- 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
@@ -18,7 +18,7 @@ class Channels extends Table {
TextColumn get config => text().map(MapConverter<Object>())();
/// 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
DateTimeColumn get lastMessageAt => dateTime().nullable()();
@@ -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.4.0-beta
version: 1.5.0
repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
@@ -11,16 +11,14 @@ environment:
dependencies:
flutter:
sdk: flutter
mutex: ^2.0.0
logging: ^0.11.4
meta: ^1.2.4
moor: ^3.4.0
mutex: ^2.0.0
path: ^1.7.0
path_provider: ^1.6.27
sqlite3_flutter_libs: ^0.4.0+1
stream_chat:
git:
url: https://github.com/GetStream/stream-chat-flutter.git
ref: develop
path: packages/stream_chat
stream_chat: ^1.5.0
dependency_overrides:
stream_chat: