fix: sort merged lists by date sent instead of falling back to the received date (bulwarkmail/webmail#1219)

This commit is contained in:
Linus Rath
2026-10-31 04:41:02 +01:00
parent 43bb5e474a
commit 04a962a69e
3 changed files with 23 additions and 2 deletions
+16
View File
@@ -0,0 +1,16 @@
import { describe, it, expect, vi } from 'vitest';
vi.mock('../jmap-client', () => ({ jmapClient: { accountId: 'acc-1', request: vi.fn() } }));
import { EMAIL_FULL_PROPERTIES, EMAIL_LIST_PROPERTIES, THREAD_HEADER_PROPERTIES } from '../email';
// Sort by "Date sent" compares sentAt on the device for a list merged from
// several accounts, but list rows never had it, so the order fell back to
// the received date (webmail #1219).
describe('list properties', () => {
it('include sentAt, once', () => {
for (const list of [EMAIL_LIST_PROPERTIES, EMAIL_FULL_PROPERTIES, THREAD_HEADER_PROPERTIES]) {
expect(list.filter((p) => p === 'sentAt')).toHaveLength(1);
}
});
});
@@ -445,6 +445,8 @@ live('live Stalwart: mail, contacts, search (0.16 and 1.0)', () => {
const row = page.list.find((e) => e.id === id);
expect(row).toBeDefined();
expect(senderWarningOf(row!)?.status).toBe('failed');
// The Date header, for sorting by date sent in merged lists (bulwarkmail/webmail#1219).
expect(typeof row!.sentAt).toBe('string');
// The full fetch reads the same verdict from `headers`.
const [full] = await getFullEmails([id]);
expect(senderWarningOf(full)?.status).toBe('failed');
+5 -2
View File
@@ -24,6 +24,9 @@ import { LIST_AUTH_RESULTS_PROPERTY } from '../lib/email-headers';
const EMAIL_SUMMARY_PROPERTIES = [
'id', 'threadId', 'mailboxIds', 'keywords', 'size',
'receivedAt', 'from', 'to', 'cc', 'subject', 'preview', 'hasAttachment',
// Sorting by "Date sent" compares it on the device for a list merged from
// several accounts; without it the order fell back to receivedAt (#1219).
'sentAt',
];
export const EMAIL_LIST_PROPERTIES = [
@@ -41,7 +44,7 @@ export const EMAIL_LIST_PROPERTIES = [
export const EMAIL_FULL_PROPERTIES = [
...EMAIL_SUMMARY_PROPERTIES,
'bodyStructure', 'textBody', 'htmlBody', 'bodyValues',
'attachments', 'blobId', 'bcc', 'replyTo', 'sentAt',
'attachments', 'blobId', 'bcc', 'replyTo',
'messageId', 'inReplyTo', 'references', 'headers',
];
@@ -1024,7 +1027,7 @@ export async function getEmailFlags(
}
// What a collapsed conversation card shows; `sentAt` is the date it prints.
export const THREAD_HEADER_PROPERTIES = [...EMAIL_LIST_PROPERTIES, 'sentAt'];
export const THREAD_HEADER_PROPERTIES = EMAIL_LIST_PROPERTIES;
/** A conversation's members, oldest first, without bodies. */
export interface ThreadHeaders {