feat: add imageProviderResolver in the ChatOptions to override the default CachedNetworkImageProvider

This commit is contained in:
Freek van de Ven 2025-02-20 14:35:10 +01:00 committed by FlutterJoey
parent a1fc65aba2
commit 5975e2f1c0
4 changed files with 54 additions and 24 deletions

View file

@ -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 - 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 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 senderTitleResolver to the ChatOptions to resolve the title of the sender in the chat message
- Added imageProviderResolver to the ChatOptions to resolve ImageProvider for all images in the userstory
## 4.0.0 ## 4.0.0
- Move to the new user story architecture - Move to the new user story architecture

View file

@ -1,3 +1,4 @@
import "package:cached_network_image/cached_network_image.dart";
import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:chat_repository_interface/chat_repository_interface.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:flutter_chat/src/config/chat_builders.dart"; import "package:flutter_chat/src/config/chat_builders.dart";
@ -23,6 +24,7 @@ class ChatOptions {
this.iconDisabledColor, this.iconDisabledColor,
this.chatAlignment, this.chatAlignment,
this.onNoChats, this.onNoChats,
this.imageProviderResolver = _defaultImageProviderResolver,
ChatRepositoryInterface? chatRepository, ChatRepositoryInterface? chatRepository,
UserRepositoryInterface? userRepository, UserRepositoryInterface? userRepository,
}) : chatRepository = chatRepository ?? LocalChatRepository(), }) : chatRepository = chatRepository ?? LocalChatRepository(),
@ -90,6 +92,11 @@ class ChatOptions {
/// [onNoChats] is a function that is triggered when there are no chats. /// [onNoChats] is a function that is triggered when there are no chats.
final Function? onNoChats; final Function? onNoChats;
/// If [imageProviderResolver] is set, it will be used to get the images for
/// the images in the entire userstory. If not provided, CachedNetworkImage
/// will be used.
final ImageProviderResolver imageProviderResolver;
} }
/// Typedef for the chatTitleResolver function that is used to get a title for /// Typedef for the chatTitleResolver function that is used to get a title for
@ -100,6 +107,13 @@ typedef ChatTitleResolver = String? Function(ChatModel chat);
/// a sender. /// a sender.
typedef SenderTitleResolver = String? Function(UserModel? user); typedef SenderTitleResolver = String? Function(UserModel? user);
/// Typedef for the imageProviderResolver function that is used to get images
/// for the userstory.
typedef ImageProviderResolver = ImageProvider Function(
BuildContext context,
Uri image,
);
/// Typedef for the messageThemeResolver function that is used to get a /// 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 /// [MessageTheme] for a message. This can return null so you can fall back to
/// default values for some messages. /// default values for some messages.
@ -252,6 +266,12 @@ MessageTheme? _defaultMessageThemeResolver(
) => ) =>
null; null;
ImageProvider _defaultImageProviderResolver(
BuildContext context,
Uri image,
) =>
CachedNetworkImageProvider(image.toString());
/// All configurable paddings and whitespaces within the userstory /// All configurable paddings and whitespaces within the userstory
class ChatSpacing { class ChatSpacing {
/// Creates a ChatSpacing object /// Creates a ChatSpacing object

View file

@ -1,4 +1,3 @@
import "package:cached_network_image/cached_network_image.dart";
import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:chat_repository_interface/chat_repository_interface.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:flutter_chat/src/config/chat_options.dart"; import "package:flutter_chat/src/config/chat_options.dart";
@ -241,7 +240,10 @@ class _DefaultChatImage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var chatScope = ChatScope.of(context);
var options = chatScope.options;
var textTheme = Theme.of(context).textTheme; var textTheme = Theme.of(context).textTheme;
var imageUrl = message.imageUrl!;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4), padding: const EdgeInsets.symmetric(horizontal: 4),
child: SizedBox( child: SizedBox(
@ -250,11 +252,12 @@ class _DefaultChatImage extends StatelessWidget {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
child: AnimatedSize( child: AnimatedSize(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
child: CachedNetworkImage( child: Image(
imageUrl: message.imageUrl!, image:
options.imageProviderResolver(context, Uri.parse(imageUrl)),
fit: BoxFit.fitWidth, fit: BoxFit.fitWidth,
errorWidget: (context, url, error) => Text( errorBuilder: (context, error, stackTrace) => Text(
"Something went wrong", "Something went wrong with loading the image",
style: textTheme.bodyLarge?.copyWith( style: textTheme.bodyLarge?.copyWith(
color: messageTheme.textColor, color: messageTheme.textColor,
), ),

View file

@ -1,4 +1,3 @@
import "package:cached_network_image/cached_network_image.dart";
import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:chat_repository_interface/chat_repository_interface.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:flutter_chat/src/services/date_formatter.dart"; import "package:flutter_chat/src/services/date_formatter.dart";
@ -159,8 +158,11 @@ class OldChatMessageBuilder extends StatelessWidget {
], ],
) )
: message.isImageMessage : message.isImageMessage
? CachedNetworkImage( ? Image(
imageUrl: message.imageUrl ?? "", image: options.imageProviderResolver(
context,
Uri.parse(message.imageUrl!),
),
) )
: const SizedBox.shrink(), : const SizedBox.shrink(),
), ),
@ -182,20 +184,24 @@ class _ChatImage extends StatelessWidget {
final String image; final String image;
@override @override
Widget build(BuildContext context) => Container( Widget build(BuildContext context) {
clipBehavior: Clip.hardEdge, var chatScope = ChatScope.of(context);
decoration: BoxDecoration( var options = chatScope.options;
color: Colors.black,
borderRadius: BorderRadius.circular(40.0), return Container(
), clipBehavior: Clip.hardEdge,
width: 40, decoration: BoxDecoration(
height: 40, color: Colors.black,
child: image.isNotEmpty borderRadius: BorderRadius.circular(40.0),
? CachedNetworkImage( ),
fadeInDuration: Duration.zero, width: 40,
imageUrl: image, height: 40,
fit: BoxFit.cover, child: image.isNotEmpty
) ? Image(
: null, fit: BoxFit.cover,
); image: options.imageProviderResolver(context, Uri.parse(image)),
)
: null,
);
}
} }