fix(email): populate mimeTree for JMAP accounts in Show Mail Structure (#92)
The JMAP body-fetch path never requested or stored `bodyStructure`, so `body.mimeTree` was always null for JMAP accounts — causing Show Mail Structure to show nothing. Fix: include `bodyStructure` in the JMAP `Email/get` request and convert it to the same JSON format used by the IMAP path via the new `_jmapBodyStructureToJson` helper. The parsed tree is persisted in the DB and returned from `getEmailBody`, so the cached round-trip also works. Tests added: - Unit: JMAP getEmailBody populates mimeTree from bodyStructure and survives the cache round-trip; null when bodyStructure is absent. - Widget: Show Mail Structure dialog displays all MIME parts when mimeTree is present; snackbar appears when mimeTree is null. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
451aceaeed
commit
ef3fb72f4e
@@ -318,9 +318,17 @@ class EmailRepositoryImpl implements EmailRepository {
|
||||
'htmlBody',
|
||||
'bodyValues',
|
||||
'attachments',
|
||||
'bodyStructure',
|
||||
],
|
||||
'fetchHTMLBodyValues': true,
|
||||
'fetchTextBodyValues': true,
|
||||
'bodyProperties': [
|
||||
'partId',
|
||||
'type',
|
||||
'name',
|
||||
'size',
|
||||
'subParts',
|
||||
],
|
||||
},
|
||||
'0',
|
||||
],
|
||||
@@ -340,6 +348,12 @@ class EmailRepositoryImpl implements EmailRepository {
|
||||
}).toList(),
|
||||
);
|
||||
|
||||
final rawBodyStructure =
|
||||
emailData['bodyStructure'] as Map<String, dynamic>?;
|
||||
final mimeTreeJson = rawBodyStructure != null
|
||||
? jsonEncode(_jmapBodyStructureToJson(rawBodyStructure))
|
||||
: null;
|
||||
|
||||
await _db.into(_db.emailBodies).insertOnConflictUpdate(
|
||||
EmailBodiesCompanion.insert(
|
||||
emailId: emailId,
|
||||
@@ -347,6 +361,7 @@ class EmailRepositoryImpl implements EmailRepository {
|
||||
htmlBody: Value(htmlBody),
|
||||
attachmentsJson: Value(attachmentsJson),
|
||||
headersJson: Value(headersJson),
|
||||
mimeTreeJson: Value(mimeTreeJson),
|
||||
cachedAt: Value(DateTime.now()),
|
||||
),
|
||||
);
|
||||
@@ -357,6 +372,7 @@ class EmailRepositoryImpl implements EmailRepository {
|
||||
htmlBody: htmlBody,
|
||||
attachments: _parseAttachments(attachmentsJson),
|
||||
headers: _parseHeaders(headersJson),
|
||||
mimeTree: _parseMimeTree(mimeTreeJson),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3018,3 +3034,16 @@ Map<String, dynamic> _mimePartToJson(imap.MimePart part) {
|
||||
/// Builds a JSON string representing the MIME tree of [msg].
|
||||
String _buildMimeTreeJson(imap.MimeMessage msg) =>
|
||||
jsonEncode(_mimePartToJson(msg));
|
||||
|
||||
/// Converts a JMAP `bodyStructure` object into the same JSON format used by
|
||||
/// [_mimePartToJson], so [_parseMimeTree] can deserialise it uniformly.
|
||||
Map<String, dynamic> _jmapBodyStructureToJson(Map<String, dynamic> m) => {
|
||||
'contentType': m['type'] as String? ?? 'application/octet-stream',
|
||||
'filename': m['name'],
|
||||
'size': m['size'],
|
||||
'encoding': null,
|
||||
'children': ((m['subParts'] as List<dynamic>?) ?? [])
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map(_jmapBodyStructureToJson)
|
||||
.toList(),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user