diff --git a/packages/stream_chat_flutter/example/lib/tutorial-part-6.dart b/packages/stream_chat_flutter/example/lib/tutorial-part-6.dart index 59dde1ee..110cc1dc 100644 --- a/packages/stream_chat_flutter/example/lib/tutorial-part-6.dart +++ b/packages/stream_chat_flutter/example/lib/tutorial-part-6.dart @@ -44,7 +44,12 @@ class MyApp extends StatelessWidget { final defaultTheme = StreamChatThemeData.fromTheme(themeData); final colorTheme = defaultTheme.colorTheme; final customTheme = defaultTheme.merge(StreamChatThemeData( - ownMessageTheme: MessageTheme( + channelPreviewTheme: ChannelPreviewTheme( + avatarTheme: AvatarTheme( + borderRadius: BorderRadius.circular(8), + ), + ), + otherMessageTheme: MessageTheme( messageBackgroundColor: colorTheme.black, messageText: TextStyle( color: colorTheme.white, diff --git a/packages/stream_chat_flutter/lib/src/channel_image.dart b/packages/stream_chat_flutter/lib/src/channel_image.dart index 649a5880..e7e39d38 100644 --- a/packages/stream_chat_flutter/lib/src/channel_image.dart +++ b/packages/stream_chat_flutter/lib/src/channel_image.dart @@ -96,7 +96,11 @@ class ChannelImage extends StatelessWidget { initialData: otherMember.user, builder: (context, snapshot) { return UserAvatar( - borderRadius: borderRadius, + borderRadius: borderRadius ?? + StreamChatTheme.of(context) + .channelPreviewTheme + .avatarTheme + .borderRadius, user: snapshot.data ?? otherMember.user, constraints: constraints ?? StreamChatTheme.of(context) @@ -120,7 +124,11 @@ class ChannelImage extends StatelessWidget { .toList(); return GroupImage( images: images, - borderRadius: borderRadius, + borderRadius: borderRadius ?? + StreamChatTheme.of(context) + .channelPreviewTheme + .avatarTheme + .borderRadius, constraints: constraints ?? StreamChatTheme.of(context) .channelPreviewTheme diff --git a/packages/stream_chat_flutter/lib/src/full_screen_media.dart b/packages/stream_chat_flutter/lib/src/full_screen_media.dart index 6da6a2e0..88c20a51 100644 --- a/packages/stream_chat_flutter/lib/src/full_screen_media.dart +++ b/packages/stream_chat_flutter/lib/src/full_screen_media.dart @@ -243,7 +243,7 @@ class VideoPackage { ChewieController get chewieController => _chewieController; - bool get initialized => _videoPlayerController.value.initialized; + bool get initialized => _videoPlayerController.value.isInitialized; VideoPackage( Attachment attachment, { diff --git a/packages/stream_chat_flutter/lib/src/image_footer.dart b/packages/stream_chat_flutter/lib/src/image_footer.dart index 7140e490..afcd0176 100644 --- a/packages/stream_chat_flutter/lib/src/image_footer.dart +++ b/packages/stream_chat_flutter/lib/src/image_footer.dart @@ -3,9 +3,10 @@ import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:dio/dio.dart'; -import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/video_thumbnail_image.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -90,27 +91,40 @@ class _ImageFooterState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - IconButton( - icon: StreamSvgIcon.iconShare( - size: 24.0, - color: StreamChatTheme.of(context).colorTheme.black, - ), - onPressed: () async { - final attachment = - widget.mediaAttachments[widget.currentPage]; - var url = attachment.imageUrl ?? - attachment.assetUrl ?? - attachment.thumbUrl; - var type = attachment.type == 'image' - ? 'jpg' - : url?.split('?')?.first?.split('.')?.last ?? 'jpg'; - var request = await HttpClient().getUrl(Uri.parse(url)); - var response = await request.close(); - var bytes = - await consolidateHttpClientResponseBytes(response); - await Share.file('File', 'image.$type', bytes, 'image/$type'); - }, - ), + kIsWeb + ? SizedBox() + : IconButton( + icon: StreamSvgIcon.iconShare( + size: 24.0, + color: StreamChatTheme.of(context).colorTheme.black, + ), + onPressed: () async { + final attachment = + widget.mediaAttachments[widget.currentPage]; + final url = attachment.imageUrl ?? + attachment.assetUrl ?? + attachment.thumbUrl; + final type = attachment.type == 'image' + ? 'jpg' + : url?.split('?')?.first?.split('.')?.last ?? 'jpg'; + final request = + await HttpClient().getUrl(Uri.parse(url)); + final response = await request.close(); + final bytes = + await consolidateHttpClientResponseBytes(response); + final tmpPath = await getTemporaryDirectory(); + final filePath = + '${tmpPath.path}/${attachment.id}.$type'; + final file = File(filePath); + await file.writeAsBytes(bytes); + await Share.shareFiles( + [filePath], + mimeTypes: [ + 'image/$type', + ], + ); + }, + ), InkWell( onTap: widget.onTitleTap, child: Container( diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 544c7d7f..bb7094f0 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -2012,9 +2012,10 @@ class MessageInputState extends State { return; } + final shouldUnfocus = _commandEnabled; + if (_commandEnabled) { text = '/${_chosenCommand.name} ' + text; - FocusScope.of(context).unfocus(); } final attachments = [..._attachments.values]; @@ -2081,6 +2082,10 @@ class MessageInputState extends State { sendingFuture = channel.updateMessage(message); } + if (!shouldUnfocus) { + FocusScope.of(context).requestFocus(_focusNode); + } + return sendingFuture.then((resp) { if (resp.message?.type == 'error') { _parseExistingMessage(message); diff --git a/packages/stream_chat_flutter/lib/src/message_search_list_view.dart b/packages/stream_chat_flutter/lib/src/message_search_list_view.dart index 165ed47b..316e27b3 100644 --- a/packages/stream_chat_flutter/lib/src/message_search_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_search_list_view.dart @@ -157,53 +157,14 @@ class _MessageSearchListViewState extends State { errorBuilder: widget.errorBuilder ?? (BuildContext context, dynamic error) { if (error is Error) { - print((error).stackTrace); - } - - var message = error.toString(); - if (error is DioError) { - if (error.type == DioErrorType.RESPONSE) { - message = error.message; - } else { - message = 'Check your connection and retry'; - } + print(error.stackTrace); } return InfoTile( showMessage: widget.showErrorTile, tileAnchor: Alignment.topCenter, childAnchor: Alignment.topCenter, message: 'An error occurred.', - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text.rich( - TextSpan( - children: [ - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(right: 2.0), - child: Icon(Icons.error_outline), - ), - ), - TextSpan(text: 'Error loading messages'), - ], - ), - style: Theme.of(context).textTheme.headline6, - ), - Padding( - padding: const EdgeInsets.only(top: 16.0), - child: Text(message), - ), - ElevatedButton( - onPressed: () { - _messageSearchListController.loadData(); - }, - child: Text('Retry'), - ), - ], - ), - ), + child: Container(), ); }, loadingBuilder: widget.loadingBuilder ?? diff --git a/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart b/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart index 50741419..4d2b2e38 100644 --- a/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart @@ -55,7 +55,7 @@ class _VideoAttachmentThumbnailState extends State<_VideoAttachmentThumbnail> { return Container( height: widget.size.height, width: widget.size.width, - child: _controller.value.initialized + child: _controller.value.isInitialized ? VideoPlayer(_controller) : CircularProgressIndicator()); } diff --git a/packages/stream_chat_flutter/lib/src/video_thumbnail_image.dart b/packages/stream_chat_flutter/lib/src/video_thumbnail_image.dart index 48f1b15b..80607b8e 100644 --- a/packages/stream_chat_flutter/lib/src/video_thumbnail_image.dart +++ b/packages/stream_chat_flutter/lib/src/video_thumbnail_image.dart @@ -67,21 +67,27 @@ class _VideoThumbnailImageState extends State { builder: (_) { if (snapshot.hasError) { return widget.errorBuilder?.call(context, snapshot.error) ?? - Center(child: StreamSvgIcon.error()); + Center( + child: StreamSvgIcon.error(), + ); } if (!snapshot.hasData) { - return widget.placeholderBuilder?.call(context) ?? - Shimmer.fromColors( - baseColor: - StreamChatTheme.of(context).colorTheme.greyGainsboro, - highlightColor: - StreamChatTheme.of(context).colorTheme.whiteSmoke, - child: Image.asset( - 'images/placeholder.png', - fit: BoxFit.cover, - package: 'stream_chat_flutter', + return Container( + constraints: BoxConstraints.expand(), + child: widget.placeholderBuilder?.call(context) ?? + Shimmer.fromColors( + baseColor: StreamChatTheme.of(context) + .colorTheme + .greyGainsboro, + highlightColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, + child: Image.asset( + 'images/placeholder.png', + fit: BoxFit.cover, + package: 'stream_chat_flutter', + ), ), - ); + ); } return Image.memory( snapshot.data, diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 610ba18b..c42849d9 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: url: https://github.com/GetStream/stream-chat-flutter.git ref: develop path: packages/stream_chat_flutter_core - photo_view: ^0.10.3 + photo_view: ^0.11.0 rxdart: ^0.25.0 scrollable_positioned_list: ^0.1.8 jiffy: ^3.0.1 @@ -27,8 +27,8 @@ dependencies: flutter_markdown: ^0.5.2 url_launcher: ^5.7.10 emojis: ^0.9.3 - video_player: ^1.0.1 - chewie: ^0.12.1+1 + video_player: ^2.0.0 + chewie: ^1.0.0 file_picker: ^2.1.5 image_picker: ^0.6.7+17 flutter_keyboard_visibility: ^4.0.2 @@ -41,11 +41,11 @@ dependencies: flutter_slidable: ^0.5.7 clipboard: ^0.1.2+8 image_gallery_saver: ^1.6.7 - esys_flutter_share: ^1.0.2 - photo_manager: ^0.6.0 + share_plus: ^1.2.0 + photo_manager: ^1.0.0 transparent_image: ^1.0.0 ezanimation: ^0.4.1 - synchronized: ^2.2.0+2 + synchronized: ^2.1.0 characters: ^1.0.0 dio: ^3.0.10 path_provider: ^1.6.27