42 lines
1.5 KiB
Dart
42 lines
1.5 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:enough_mail/enough_mail.dart' as imap;
|
|
|
|
/// Replaces `src="cid:..."` references in [html] with inline `data:` URIs
|
|
/// by looking up each Content-ID in the MIME tree of [msg].
|
|
///
|
|
/// Emails with `multipart/related` often embed images this way. Without
|
|
/// substitution the WebView shows broken image icons even after the full
|
|
/// message has been downloaded.
|
|
String injectInlineImages(String html, imap.MimeMessage msg) {
|
|
final inlineParts = msg.findContentInfo(
|
|
disposition: imap.ContentDisposition.inline,
|
|
);
|
|
if (inlineParts.isEmpty) return html;
|
|
|
|
var result = html;
|
|
for (final info in inlineParts) {
|
|
final cid = info.cid;
|
|
if (cid == null || cid.isEmpty) continue;
|
|
final bareCid = cid.startsWith('<') && cid.endsWith('>')
|
|
? cid.substring(1, cid.length - 1)
|
|
: cid;
|
|
|
|
final part = msg.getPart(info.fetchId);
|
|
if (part == null) continue;
|
|
final bytes = part.decodeContentBinary();
|
|
if (bytes == null || bytes.isEmpty) continue;
|
|
|
|
final contentType =
|
|
info.contentType?.mediaType.text ?? 'application/octet-stream';
|
|
final dataUri = 'data:$contentType;base64,${base64.encode(bytes)}';
|
|
|
|
result = result
|
|
.replaceAll('src="cid:$bareCid"', 'src="$dataUri"')
|
|
.replaceAll("src='cid:$bareCid'", "src='$dataUri'")
|
|
.replaceAll('src="cid:${bareCid.toLowerCase()}"', 'src="$dataUri"')
|
|
.replaceAll("src='cid:${bareCid.toLowerCase()}'", "src='$dataUri'");
|
|
}
|
|
return result;
|
|
}
|