diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx
index 74fa0bc1..4786426b 100644
--- a/app/[locale]/page.tsx
+++ b/app/[locale]/page.tsx
@@ -1504,6 +1504,43 @@ export default function Home() {
}
};
+ const handleImportEmailFromContextMenu = (mailboxId: string) => {
+ if (!client) return;
+ const mailbox = mailboxes.find(mb => mb.id === mailboxId);
+ if (!mailbox) return;
+ const targetMailboxId = mailbox.originalId || mailbox.id;
+
+ const input = document.createElement('input');
+ input.type = 'file';
+ input.accept = '.eml,message/rfc822';
+ input.multiple = true;
+ input.onchange = async (e) => {
+ const files = Array.from((e.target as HTMLInputElement).files ?? []);
+ if (files.length === 0) return;
+
+ let imported = 0;
+ let failed = 0;
+ for (const file of files) {
+ try {
+ const blob = new Blob([await file.arrayBuffer()], { type: 'message/rfc822' });
+ await client.importRawEmail(blob, { [targetMailboxId]: true }, { '$seen': true });
+ imported++;
+ } catch {
+ failed++;
+ }
+ }
+
+ if (imported > 0) {
+ toast.success(t('notifications.import_email_success'));
+ if (selectedMailbox) await fetchEmails(client, selectedMailbox);
+ }
+ if (failed > 0) {
+ toast.error(t('notifications.import_email_error'));
+ }
+ };
+ input.click();
+ };
+
const handleRefreshMailboxes = async () => {
if (!client) return;
try {
@@ -1894,6 +1931,7 @@ export default function Home() {
onCreateFolder={handleCreateFolderFromContextMenu}
onRenameFolder={handleRenameFolderFromContextMenu}
onDeleteFolder={handleDeleteFolderFromContextMenu}
+ onImportEmail={handleImportEmailFromContextMenu}
onRefreshMailboxes={handleRefreshMailboxes}
onCompose={() => {
setComposerMode('compose');
diff --git a/components/layout/mailbox-context-menu.tsx b/components/layout/mailbox-context-menu.tsx
index 0f497d96..5807d085 100644
--- a/components/layout/mailbox-context-menu.tsx
+++ b/components/layout/mailbox-context-menu.tsx
@@ -20,6 +20,7 @@ import {
Pencil,
FolderX,
RefreshCw,
+ Upload,
} from "lucide-react";
interface Position {
@@ -84,6 +85,7 @@ interface MailboxContextMenuProps {
onCreateFolder?: () => void;
onRenameFolder?: (mailboxId: string) => void;
onDeleteFolder?: (mailboxId: string) => void;
+ onImportEmail?: (mailboxId: string) => void;
onRefresh?: () => void;
}
@@ -102,6 +104,7 @@ export function MailboxContextMenu({
onCreateFolder,
onRenameFolder,
onDeleteFolder,
+ onImportEmail,
onRefresh,
}: MailboxContextMenuProps) {
const t = useTranslations("mailbox_context_menu");
@@ -149,6 +152,7 @@ export function MailboxContextMenu({
const canCreateChild = mailbox.myRights?.mayCreateChild !== false;
const canSetSeen = mailbox.myRights?.maySetSeen !== false;
const canRemoveItems = mailbox.myRights?.mayRemoveItems !== false;
+ const canAddItems = mailbox.myRights?.mayAddItems !== false;
const fullPath = getMailboxPath(mailbox, mailboxes);
@@ -190,6 +194,15 @@ export function MailboxContextMenu({
+ handleAction(() => onImportEmail?.(mailbox.id))}
+ disabled={!onImportEmail || !canAddItems}
+ />
+
+
+
void;
onRenameFolder?: (mailboxId: string) => void;
onDeleteFolder?: (mailboxId: string) => void;
+ onImportEmail?: (mailboxId: string) => void;
onRefreshMailboxes?: () => void;
className?: string;
}
@@ -636,6 +637,7 @@ export function Sidebar({
onCreateFolder,
onRenameFolder,
onDeleteFolder,
+ onImportEmail,
onRefreshMailboxes,
className,
}: SidebarProps) {
@@ -1037,6 +1039,7 @@ export function Sidebar({
onCreateFolder={onCreateFolder}
onRenameFolder={onRenameFolder}
onDeleteFolder={onDeleteFolder}
+ onImportEmail={onImportEmail}
onRefresh={onRefreshMailboxes}
/>
diff --git a/locales/en/common.json b/locales/en/common.json
index 8d6cd951..2aeef7dd 100644
--- a/locales/en/common.json
+++ b/locales/en/common.json
@@ -1684,6 +1684,7 @@
"new_subfolder": "New subfolder...",
"new_folder": "New folder...",
"rename": "Rename...",
+ "import_email": "Import .eml...",
"empty_folder": "Empty folder",
"empty_folder_generic": "Empty folder",
"delete_folder": "Delete folder",