mirror of
https://github.com/bulwarkmail/native.git
synced 2026-10-31 08:06:36 +00:00
fix: mark a message read when the notification's Delete moves it to Trash and the delete action says so #86
This commit is contained in:
@@ -288,6 +288,40 @@ describe('pushBackgroundTask notifications', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['trash-and-read', { mailboxIds: { 'trash-box': true }, 'keywords/$seen': true }],
|
||||
['trash', { mailboxIds: { 'trash-box': true } }],
|
||||
// Never destroyed from a notification (#68), but not marked read either.
|
||||
['permanent', { mailboxIds: { 'trash-box': true } }],
|
||||
])('follows the delete action setting "%s" (#86)', async (deleteAction, patch) => {
|
||||
await AsyncStorage.setItem('webmail:settings:v1', JSON.stringify({ deleteAction }));
|
||||
const postCalls: any[] = [];
|
||||
(secureFetch as ReturnType<typeof vi.fn>).mockImplementation(async (url: string, opts?: any) => {
|
||||
if (opts?.body) postCalls.push(JSON.parse(opts.body));
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => (url.endsWith('/.well-known/jmap')
|
||||
? {
|
||||
apiUrl: 'https://mail.example.com/jmap/',
|
||||
primaryAccounts: { 'urn:ietf:params:jmap:mail': 'jmap-primary' },
|
||||
accounts: { 'jmap-primary': {} },
|
||||
}
|
||||
: {
|
||||
methodResponses: [
|
||||
['Mailbox/get', { list: [{ id: 'trash-box', role: 'trash' }] }, '0'],
|
||||
['Email/set', { updated: { m1: {} } }, '0'],
|
||||
],
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
await handleNotificationAction({ action: 'delete', emailId: 'm1', accountId: LOCAL });
|
||||
|
||||
expect(postCalls[1].methodCalls).toEqual([
|
||||
['Email/set', { accountId: 'jmap-primary', update: { m1: patch } }, '0'],
|
||||
]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['has no trash mailbox', ['Mailbox/get', { list: [{ id: 'inbox', role: 'inbox' }] }, '0']],
|
||||
['cannot list mailboxes', ['error', { type: 'accountNotFound' }, '0']],
|
||||
|
||||
@@ -51,6 +51,7 @@ const EMAIL_PROPERTIES = [
|
||||
interface PushPersistedSettings {
|
||||
emailNotificationsEnabled?: boolean;
|
||||
senderFavicons?: boolean;
|
||||
deleteAction?: string;
|
||||
}
|
||||
|
||||
async function emailNotificationsAllowed(): Promise<boolean> {
|
||||
@@ -78,6 +79,20 @@ export async function senderFaviconsAllowed(): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
|
||||
// The "Delete Action" setting, as far as a notification's Delete honours it:
|
||||
// "Move to Trash and mark as read" marks the message read on the way (#86).
|
||||
// "Delete Permanently" still only moves to Trash: a notification never
|
||||
// destroys mail (#68).
|
||||
async function notificationDeleteMarksRead(): Promise<boolean> {
|
||||
try {
|
||||
const raw = await AsyncStorage.getItem(SETTINGS_STORAGE_KEY);
|
||||
if (!raw) return false;
|
||||
return (JSON.parse(raw) as PushPersistedSettings).deleteAction === 'trash-and-read';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** The app's language: the in-app override, else the device's. */
|
||||
export async function notificationLocale(): Promise<LocaleCode> {
|
||||
try {
|
||||
@@ -665,13 +680,15 @@ export async function handleNotificationAction(data: unknown): Promise<void> {
|
||||
console.warn('[push] no trash mailbox for notification delete', emailAccountId);
|
||||
return;
|
||||
}
|
||||
const patch: Record<string, unknown> = { mailboxIds: { [trash.id]: true } };
|
||||
if (await notificationDeleteMarksRead()) patch['keywords/$seen'] = true;
|
||||
const res = await jmapPost(session, [
|
||||
[
|
||||
'Email/set',
|
||||
{
|
||||
accountId: emailAccountId,
|
||||
update: {
|
||||
[emailId]: { mailboxIds: { [trash.id]: true } },
|
||||
[emailId]: patch,
|
||||
},
|
||||
},
|
||||
'0',
|
||||
|
||||
Reference in New Issue
Block a user