fix(mail): sync Object error, MIME subject decoding, sticky compact pagination
- Fix sync error: backend returns {synced, error?} not {success, synced_count}; frontend now checks error field
- Decode MIME encoded-words (=?UTF-8?Q?...?=) in backend during IMAP sync for subject/from/to/cc headers
- Add frontend decodeMimeHeader() utility for already-stored encoded subjects (MailList + MailDetail)
- Make pagination sticky at bottom of mail list (flex-col h-full, ul scrolls, pagination flex-shrink-0)
- Make pagination compact: smaller padding (px-1.5 py-0.5), text-xs, smaller icons, tighter spacing
This commit is contained in:
@@ -381,8 +381,40 @@ export function testConnection(accountId: string): Promise<{ success: boolean; m
|
||||
return apiPost<{ success: boolean; message: string }>(`/mail/accounts/${accountId}/test-connection`);
|
||||
}
|
||||
|
||||
export function triggerSync(accountId: string): Promise<{ success: boolean; synced_count: number }> {
|
||||
return apiPost<{ success: boolean; synced_count: number }>(`/mail/accounts/${accountId}/sync`);
|
||||
export function triggerSync(accountId: string): Promise<{ synced: number; error?: string }> {
|
||||
return apiPost<{ synced: number; error?: string }>(`/mail/accounts/${accountId}/sync`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode MIME encoded-words (=?UTF-8?Q?...?=) to readable text.
|
||||
* Used for mail subjects/from names that were stored before backend decoding was added.
|
||||
*/
|
||||
export function decodeMimeHeader(value: string | undefined | null): string {
|
||||
if (!value) return '';
|
||||
// Check if value contains MIME encoded-words
|
||||
if (!value.includes('=?')) return value;
|
||||
try {
|
||||
// Decode all encoded-words in the string
|
||||
return value.replace(/=\?([^?]+)\?([BQ])\?([^?]*)\?=/gi, (_match, _charset, encoding, encoded) => {
|
||||
try {
|
||||
if (encoding.toUpperCase() === 'B') {
|
||||
// Base64 decode
|
||||
const decoded = atob(encoded);
|
||||
return decodeURIComponent(escape(decoded));
|
||||
} else {
|
||||
// Q encoding: replace _ with space, then decode =XX hex sequences
|
||||
const qDecoded = encoded.replace(/_/g, ' ').replace(/=([0-9A-F]{2})/gi, (_m, hex) => {
|
||||
return String.fromCharCode(parseInt(hex, 16));
|
||||
});
|
||||
return decodeURIComponent(escape(qDecoded));
|
||||
}
|
||||
} catch {
|
||||
return _match;
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Folders ────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user