Productivity features, UI translations, local email translation
- Snooze (with a Snoozed folder), keyboard shortcuts with a Settings section, mail templates (Compose > More > Templates), a Subscriptions folder with bulk unsubscribe/delete, and tracker blocking with a Privacy toggle (on by default) - Own dialogs instead of browser popups; emoji picker in compose; compose windows survive a visit to Settings - Sentence completion learned from the user's sent mail (no AI) - Interface in English and Polish (one file per language, English as the fallback), picked from the browser on first run, then kept - Email translation on the server via LibreTranslate: Translate button and "Translate to...", messages in several languages translated part by part, names/addresses/emoji/file names/phone numbers kept, an animated line while translating - Antispam "Mark as spam" loads with the message, not when the menu opens Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,15 +15,22 @@ export default function mount(el, ctx, props) {
|
||||
const messageId = props && props.messageId;
|
||||
if (!messageId) return;
|
||||
let disposed = false;
|
||||
let generation = 0;
|
||||
|
||||
(async () => {
|
||||
// The host mounts this with the message (hidden in a closed menu), not when
|
||||
// the menu opens, so the item is ready by then. It loads again after a
|
||||
// lesson, so a reopened menu shows the new state without a wait.
|
||||
const load = async () => {
|
||||
const mine = ++generation;
|
||||
let data = null;
|
||||
try {
|
||||
data = await ctx.api.pluginFetch(`/context/${messageId}`);
|
||||
} catch {
|
||||
return; // no antispam service, no menu item
|
||||
}
|
||||
if (disposed || !data) return;
|
||||
if (disposed || mine !== generation) return;
|
||||
el.innerHTML = "";
|
||||
if (!data) return;
|
||||
|
||||
// The folder decides which action is on offer — FIRST. A message sitting in
|
||||
// the spam folder offers "not spam" no matter what it was taught, because
|
||||
@@ -52,10 +59,15 @@ export default function mount(el, ctx, props) {
|
||||
/* the menu is closing regardless; nothing useful to show here */
|
||||
}
|
||||
});
|
||||
})();
|
||||
};
|
||||
|
||||
const onLearned = () => void load();
|
||||
window.addEventListener("webmail:antispam-learned", onLearned);
|
||||
void load();
|
||||
|
||||
return () => {
|
||||
disposed = true;
|
||||
window.removeEventListener("webmail:antispam-learned", onLearned);
|
||||
el.innerHTML = "";
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user