feat: enhance markdown image handling with customizable builder
- Introduced an `imageBuilderOverride` parameter in the `ConduitMarkdown` class to allow customization of how markdown images are rendered. - Updated the `StreamingMarkdownWidget` to accept the new `imageBuilderOverride` parameter, enabling enhanced image handling in streaming contexts. - Implemented an `imageBuilderOverride` in the `_AssistantMessageWidgetState` to utilize `EnhancedImageAttachment`, providing caching, authentication headers, and fullscreen viewing for markdown images. - Refactored the `_ImageBuilder` class to support the new image building logic, improving flexibility and maintainability of image rendering in markdown content.
This commit is contained in:
@@ -29,6 +29,7 @@ class ConduitMarkdown {
|
||||
bool selectable = true,
|
||||
bool shrinkWrap = false,
|
||||
ScrollPhysics? physics,
|
||||
Widget Function(Uri uri, String? title, String? alt)? imageBuilderOverride,
|
||||
}) {
|
||||
return MarkdownBody(
|
||||
data: data,
|
||||
@@ -36,6 +37,11 @@ class ConduitMarkdown {
|
||||
shrinkWrap: shrinkWrap,
|
||||
styleSheet: _buildStyleSheet(context),
|
||||
builders: _buildCustomBuilders(context, onTapLink),
|
||||
// Allow callers to override how markdown images render (e.g., to use
|
||||
// EnhancedImageAttachment in assistant views). Fallback to default.
|
||||
imageBuilder: (uri, title, alt) => imageBuilderOverride != null
|
||||
? imageBuilderOverride(uri, title, alt)
|
||||
: _ImageBuilder(context).buildFromUri(uri),
|
||||
extensionSet: md.ExtensionSet.gitHubFlavored,
|
||||
onTapLink: onTapLink != null
|
||||
? (text, href, title) => onTapLink(href ?? '', title)
|
||||
@@ -51,6 +57,7 @@ class ConduitMarkdown {
|
||||
required String data,
|
||||
MarkdownLinkTapCallback? onTapLink,
|
||||
bool selectable = true,
|
||||
Widget Function(Uri uri, String? title, String? alt)? imageBuilderOverride,
|
||||
}) {
|
||||
return build(
|
||||
context: context,
|
||||
@@ -58,6 +65,7 @@ class ConduitMarkdown {
|
||||
onTapLink: onTapLink,
|
||||
selectable: selectable,
|
||||
shrinkWrap: true,
|
||||
imageBuilderOverride: imageBuilderOverride,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -141,7 +149,6 @@ class ConduitMarkdown {
|
||||
) {
|
||||
return {
|
||||
'code': _CodeBlockBuilder(context),
|
||||
'img': _ImageBuilder(context),
|
||||
'mermaid': _MermaidBuilder(context),
|
||||
'latex': _LatexBuilder(context),
|
||||
'details': _DetailsBuilder(context),
|
||||
@@ -345,22 +352,23 @@ class _ImageBuilder extends MarkdownElementBuilder {
|
||||
|
||||
@override
|
||||
Widget? visitElementAfter(md.Element element, TextStyle? preferredStyle) {
|
||||
final theme = context.conduitTheme;
|
||||
final url = element.attributes['src'] ?? '';
|
||||
final uri = Uri.tryParse(url);
|
||||
|
||||
if (uri == null) {
|
||||
return _buildImageError(context, theme);
|
||||
return _buildImageError(context, context.conduitTheme);
|
||||
}
|
||||
return buildFromUri(uri);
|
||||
}
|
||||
|
||||
/// Public helper used by the Markdown `imageBuilder` callback.
|
||||
Widget buildFromUri(Uri uri) {
|
||||
final theme = context.conduitTheme;
|
||||
if (uri.scheme == 'data') {
|
||||
return _buildBase64Image(uri.toString(), context, theme);
|
||||
}
|
||||
|
||||
if (uri.scheme.isEmpty || uri.scheme == 'http' || uri.scheme == 'https') {
|
||||
return _buildNetworkImage(uri.toString(), context, theme);
|
||||
}
|
||||
|
||||
return _buildImageError(context, theme);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,11 +13,14 @@ class StreamingMarkdownWidget extends StatelessWidget {
|
||||
required this.content,
|
||||
required this.isStreaming,
|
||||
this.onTapLink,
|
||||
this.imageBuilderOverride,
|
||||
});
|
||||
|
||||
final String content;
|
||||
final bool isStreaming;
|
||||
final MarkdownLinkTapCallback? onTapLink;
|
||||
final Widget Function(Uri uri, String? title, String? alt)?
|
||||
imageBuilderOverride;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -34,6 +37,7 @@ class StreamingMarkdownWidget extends StatelessWidget {
|
||||
data: data,
|
||||
onTapLink: onTapLink,
|
||||
selectable: false,
|
||||
imageBuilderOverride: imageBuilderOverride,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user