feat: add new plugin ui.rerenderFetchedEmails method

This commit is contained in:
Paulhenry Saux
2026-07-22 13:39:21 +02:00
parent 0e47c3b039
commit 07c473e057
4 changed files with 22 additions and 1 deletions
+8
View File
@@ -63,6 +63,7 @@ const PERM_PER_METHOD: Record<string, Permission | null> = {
'ui.alert': null,
'ui.prompt': null,
'ui.rerenderEmail': null,
'ui.rerenderFetchedEmails': null,
'ui.openExternalUrl': null,
'ui.downloadFile': 'ui:download-file'
};
@@ -653,6 +654,13 @@ export async function dispatchApiCall(
window.dispatchEvent(new CustomEvent('plugin:rerender-email'));
return undefined;
}
case 'ui.rerenderFetchedEmails': {
// Re-run the onEmailsFetched hook for the currently shown message list.
// Used by crypto plugins after they change decryption state s
// so the preview or others properties re-decrypts without a full reload.
window.dispatchEvent(new CustomEvent('plugin:rerender-fetched-emails'));
return undefined;
}
case 'ui.openExternalUrl': {
const url = String(args[0] ?? '');
// Only http(s) - the sandbox should not be able to navigate the host
+1 -1
View File
@@ -246,7 +246,7 @@ export const API_METHODS = [
'upfiles.get', 'upfiles.save',
'admin.getConfig', 'admin.getAllConfig', 'admin.setConfig', 'admin.deleteConfig',
'toast.success', 'toast.error', 'toast.info', 'toast.warning',
'ui.confirm', 'ui.alert', 'ui.prompt', 'ui.rerenderEmail', 'ui.openExternalUrl', 'ui.downloadFile'
'ui.confirm', 'ui.alert', 'ui.prompt', 'ui.rerenderEmail', 'ui.rerenderFetchedEmails', 'ui.openExternalUrl', 'ui.downloadFile'
] as const;
export type ApiMethod = (typeof API_METHODS)[number];
+1
View File
@@ -241,6 +241,7 @@ function buildPluginApi(manifest: PluginManifest) {
/** Re-runs the onRenderEmailBody hook for the open message (e.g. after a
* crypto plugin unlocks a key) so its body re-renders without a reload. */
rerenderEmail: () => callApi('ui.rerenderEmail', []) as Promise<void>,
rerenderFetchedEmails: () => callApi('ui.rerenderFetchedEmails', []) as Promise<void>,
/** Opens an http/https URL in a new tab via host `window.open`. */
openExternalUrl: (url: string, target?: string) =>
callApi('ui.openExternalUrl', [url, target]) as Promise<void>,
+12
View File
@@ -757,6 +757,18 @@ function findTrashMailbox(
});
}
// Plugin re-render for already fetched emails.
// Plugins can trigger: window.dispatchEvent(new Event('plugin:rerender-fetched-emails'))
if (typeof window !== 'undefined') {
window.addEventListener('plugin:rerender-fetched-emails', async () => {
const state = useEmailStore.getState();
const transformed = await emailHooks.onEmailsFetched.transform(state.emails);
useEmailStore.setState({
emails: annotateScheduledEmails(transformed, state.scheduledSubmissionByEmailId),
});
});
}
export const useEmailStore = create<EmailStore>((set, get) => ({
emails: [],
mailboxes: [],