diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e402ef..0c48f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Changed the ChatBottomInputSection to be multiline and go from 45px to 120px in height depending on how many lines are in the textfield - Added chatScreenBuilder to the userstory configuration to customize the specific chat screen with a ChatModel as argument - Added senderTitleResolver to the ChatOptions to resolve the title of the sender in the chat message +- Added imageAuthenticationResolver to the ChatOptions to resolve the authentication headers for CachedNetworkImage for all images in the userstory ## 4.0.0 - Move to the new user story architecture diff --git a/packages/flutter_chat/lib/src/config/chat_options.dart b/packages/flutter_chat/lib/src/config/chat_options.dart index 7cf3a51..093adea 100644 --- a/packages/flutter_chat/lib/src/config/chat_options.dart +++ b/packages/flutter_chat/lib/src/config/chat_options.dart @@ -23,6 +23,7 @@ class ChatOptions { this.iconDisabledColor, this.chatAlignment, this.onNoChats, + this.imageAuthenticationResolver, ChatRepositoryInterface? chatRepository, UserRepositoryInterface? userRepository, }) : chatRepository = chatRepository ?? LocalChatRepository(), @@ -90,6 +91,11 @@ class ChatOptions { /// [onNoChats] is a function that is triggered when there are no chats. final Function? onNoChats; + + /// If [imageAuthenticationResolver] is set, it will be used to get the + /// authentication headers for an image. The [imageUrl] is provided to allow + /// for different authentication headers for different images. + final ImageAuthenticationResolver? imageAuthenticationResolver; } /// Typedef for the chatTitleResolver function that is used to get a title for @@ -100,6 +106,12 @@ typedef ChatTitleResolver = String? Function(ChatModel chat); /// a sender. typedef SenderTitleResolver = String? Function(UserModel? user); +/// Typedef for the imageAuthenticationResolver function that is used to get +/// authentication headers for an image. +typedef ImageAuthenticationResolver = Map? Function( + String imageUrl, +); + /// Typedef for the messageThemeResolver function that is used to get a /// [MessageTheme] for a message. This can return null so you can fall back to /// default values for some messages. diff --git a/packages/flutter_chat/lib/src/screens/chat_detail/widgets/default_message_builder.dart b/packages/flutter_chat/lib/src/screens/chat_detail/widgets/default_message_builder.dart index dd55e24..3c2dce2 100644 --- a/packages/flutter_chat/lib/src/screens/chat_detail/widgets/default_message_builder.dart +++ b/packages/flutter_chat/lib/src/screens/chat_detail/widgets/default_message_builder.dart @@ -241,7 +241,10 @@ class _DefaultChatImage extends StatelessWidget { @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var textTheme = Theme.of(context).textTheme; + var imageUrl = message.imageUrl!; return Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: SizedBox( @@ -251,10 +254,11 @@ class _DefaultChatImage extends StatelessWidget { child: AnimatedSize( duration: const Duration(milliseconds: 300), child: CachedNetworkImage( - imageUrl: message.imageUrl!, + imageUrl: imageUrl, fit: BoxFit.fitWidth, + httpHeaders: options.imageAuthenticationResolver?.call(imageUrl), errorWidget: (context, url, error) => Text( - "Something went wrong", + "Something went wrong with loading the image", style: textTheme.bodyLarge?.copyWith( color: messageTheme.textColor, ), diff --git a/packages/flutter_chat/lib/src/screens/chat_detail/widgets/old_message_builder.dart b/packages/flutter_chat/lib/src/screens/chat_detail/widgets/old_message_builder.dart index 1ed8fcc..9729f2e 100644 --- a/packages/flutter_chat/lib/src/screens/chat_detail/widgets/old_message_builder.dart +++ b/packages/flutter_chat/lib/src/screens/chat_detail/widgets/old_message_builder.dart @@ -161,6 +161,8 @@ class OldChatMessageBuilder extends StatelessWidget { : message.isImageMessage ? CachedNetworkImage( imageUrl: message.imageUrl ?? "", + httpHeaders: options.imageAuthenticationResolver + ?.call(message.imageUrl ?? ""), ) : const SizedBox.shrink(), ), @@ -182,20 +184,26 @@ class _ChatImage extends StatelessWidget { final String image; @override - Widget build(BuildContext context) => Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - color: Colors.black, - borderRadius: BorderRadius.circular(40.0), - ), - width: 40, - height: 40, - child: image.isNotEmpty - ? CachedNetworkImage( - fadeInDuration: Duration.zero, - imageUrl: image, - fit: BoxFit.cover, - ) - : null, - ); + Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; + + return Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.black, + borderRadius: BorderRadius.circular(40.0), + ), + width: 40, + height: 40, + child: image.isNotEmpty + ? CachedNetworkImage( + fadeInDuration: Duration.zero, + imageUrl: image, + httpHeaders: options.imageAuthenticationResolver?.call(image), + fit: BoxFit.cover, + ) + : null, + ); + } }