feat: implement empty folder functionality for junk and trash mailboxes with confirmation dialog
This commit is contained in:
@@ -473,12 +473,14 @@ export default function Home() {
|
|||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
if (!client || !selectedEmail) return;
|
if (!client || !selectedEmail) return;
|
||||||
|
|
||||||
// Check if we're currently in the trash folder
|
// Check if we're currently in the trash or junk folder
|
||||||
const currentMailbox = mailboxes.find(m => m.id === selectedMailbox);
|
const currentMailbox = mailboxes.find(m => m.id === selectedMailbox);
|
||||||
const isInTrash = currentMailbox?.role === 'trash';
|
const isInTrash = currentMailbox?.role === 'trash';
|
||||||
|
const isInJunk = currentMailbox?.role === 'junk';
|
||||||
|
const permanentlyDeleteJunk = useSettingsStore.getState().permanentlyDeleteJunk;
|
||||||
|
|
||||||
if (isInTrash) {
|
if (isInTrash || (isInJunk && permanentlyDeleteJunk)) {
|
||||||
// In trash: confirm before permanently deleting
|
// In trash or junk with permanent delete enabled: confirm before permanently deleting
|
||||||
const confirmed = await confirmDialog({
|
const confirmed = await confirmDialog({
|
||||||
title: t('email_list.permanent_delete_confirm_title'),
|
title: t('email_list.permanent_delete_confirm_title'),
|
||||||
message: t('email_list.permanent_delete_confirm_message'),
|
message: t('email_list.permanent_delete_confirm_message'),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Email, ThreadGroup } from "@/lib/jmap/types";
|
|||||||
import { ThreadListItem } from "./thread-list-item";
|
import { ThreadListItem } from "./thread-list-item";
|
||||||
import { EmailContextMenu } from "./email-context-menu";
|
import { EmailContextMenu } from "./email-context-menu";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { Trash2, Mail, MailX, MailOpen, Loader2, SearchX } from "lucide-react";
|
import { Trash2, Mail, MailX, MailOpen, Loader2, SearchX, AlertTriangle } from "lucide-react";
|
||||||
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { ConfirmDialog } from "@/components/ui/confirm-dialog";
|
import { ConfirmDialog } from "@/components/ui/confirm-dialog";
|
||||||
@@ -74,6 +74,7 @@ export function EmailList({
|
|||||||
isLoadingMore,
|
isLoadingMore,
|
||||||
mailboxes,
|
mailboxes,
|
||||||
selectedMailbox,
|
selectedMailbox,
|
||||||
|
emptyMailbox,
|
||||||
expandedThreadIds,
|
expandedThreadIds,
|
||||||
threadEmailsCache,
|
threadEmailsCache,
|
||||||
isLoadingThread,
|
isLoadingThread,
|
||||||
@@ -172,6 +173,28 @@ export function EmailList({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const currentMailbox = mailboxes.find(m => m.id === selectedMailbox);
|
||||||
|
const isEmptyableFolder = currentMailbox?.role === 'trash' || currentMailbox?.role === 'junk';
|
||||||
|
|
||||||
|
const handleEmptyFolder = async () => {
|
||||||
|
if (!client || isProcessing || !currentMailbox) return;
|
||||||
|
|
||||||
|
const confirmed = await confirmDialog({
|
||||||
|
title: t('empty_folder.confirm_title'),
|
||||||
|
message: t('empty_folder.confirm_message'),
|
||||||
|
confirmText: t('empty_folder.confirm_button'),
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
if (!confirmed) return;
|
||||||
|
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await emptyMailbox(client, currentMailbox.id);
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => setIsProcessing(false), 500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleLoadMore = useCallback(() => {
|
const handleLoadMore = useCallback(() => {
|
||||||
if (client && hasMoreEmails && !isLoadingMore && !isLoading) {
|
if (client && hasMoreEmails && !isLoadingMore && !isLoading) {
|
||||||
loadMoreEmails(client);
|
loadMoreEmails(client);
|
||||||
@@ -308,7 +331,29 @@ export function EmailList({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Empty Folder Banner for Junk/Trash */}
|
||||||
|
{isEmptyableFolder && emails.length > 0 && !hasSelection && (
|
||||||
|
<div className="px-4 py-2 border-b border-border bg-muted/30 flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
|
<AlertTriangle className="w-4 h-4" />
|
||||||
|
<span>{currentMailbox?.role === 'junk' ? t('empty_folder.junk_hint') : t('empty_folder.trash_hint')}</span>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={handleEmptyFolder}
|
||||||
|
disabled={isProcessing}
|
||||||
|
className="text-destructive border-destructive/30 hover:bg-destructive/10 text-xs"
|
||||||
|
>
|
||||||
|
{isProcessing ? (
|
||||||
|
<Loader2 className="w-3 h-3 animate-spin mr-1" />
|
||||||
|
) : (
|
||||||
|
<Trash2 className="w-3 h-3 mr-1" />
|
||||||
|
)}
|
||||||
|
{t('empty_folder.button')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Email List */}
|
{/* Email List */}
|
||||||
<div ref={parentRef} className="flex-1 overflow-y-auto bg-background relative">
|
<div ref={parentRef} className="flex-1 overflow-y-auto bg-background relative">
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export function EmailSettings() {
|
|||||||
const {
|
const {
|
||||||
markAsReadDelay,
|
markAsReadDelay,
|
||||||
deleteAction,
|
deleteAction,
|
||||||
|
permanentlyDeleteJunk,
|
||||||
showPreview,
|
showPreview,
|
||||||
emailsPerPage,
|
emailsPerPage,
|
||||||
externalContentPolicy,
|
externalContentPolicy,
|
||||||
@@ -65,6 +66,14 @@ export function EmailSettings() {
|
|||||||
</div>
|
</div>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
|
||||||
|
{/* Permanently Delete Junk */}
|
||||||
|
<SettingItem label={t('permanently_delete_junk.label')} description={t('permanently_delete_junk.description')}>
|
||||||
|
<ToggleSwitch
|
||||||
|
checked={permanentlyDeleteJunk}
|
||||||
|
onChange={(checked) => updateSetting('permanentlyDeleteJunk', checked)}
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
|
|
||||||
{/* Show Preview */}
|
{/* Show Preview */}
|
||||||
<SettingItem label={t('show_preview.label')} description={t('show_preview.description')}>
|
<SettingItem label={t('show_preview.label')} description={t('show_preview.description')}>
|
||||||
<ToggleSwitch checked={showPreview} onChange={(checked) => updateSetting('showPreview', checked)} />
|
<ToggleSwitch checked={showPreview} onChange={(checked) => updateSetting('showPreview', checked)} />
|
||||||
|
|||||||
@@ -808,6 +808,34 @@ export class JMAPClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async emptyMailbox(mailboxId: string): Promise<number> {
|
||||||
|
let totalDestroyed = 0;
|
||||||
|
let hasMore = true;
|
||||||
|
|
||||||
|
while (hasMore) {
|
||||||
|
const response = await this.request([
|
||||||
|
["Email/query", {
|
||||||
|
accountId: this.accountId,
|
||||||
|
filter: { inMailbox: mailboxId },
|
||||||
|
limit: 500,
|
||||||
|
}, "0"],
|
||||||
|
["Email/set", {
|
||||||
|
accountId: this.accountId,
|
||||||
|
"#destroy": { resultOf: "0", name: "Email/query", path: "/ids" },
|
||||||
|
}, "1"],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const queryResult = response.methodResponses?.[0]?.[1];
|
||||||
|
const setResult = response.methodResponses?.[1]?.[1];
|
||||||
|
const destroyed = setResult?.destroyed?.length || 0;
|
||||||
|
totalDestroyed += destroyed;
|
||||||
|
|
||||||
|
hasMore = destroyed > 0 && (queryResult?.total || 0) > destroyed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalDestroyed;
|
||||||
|
}
|
||||||
|
|
||||||
async markAsSpam(emailId: string, accountId?: string): Promise<void> {
|
async markAsSpam(emailId: string, accountId?: string): Promise<void> {
|
||||||
const targetAccountId = accountId || this.accountId;
|
const targetAccountId = accountId || this.accountId;
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -130,7 +130,15 @@
|
|||||||
"permanent_delete": "Endgültig löschen",
|
"permanent_delete": "Endgültig löschen",
|
||||||
"permanent_delete_confirm_title": "Endgültig löschen",
|
"permanent_delete_confirm_title": "Endgültig löschen",
|
||||||
"permanent_delete_confirm_message": "Diese E-Mail wird endgültig gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.",
|
"permanent_delete_confirm_message": "Diese E-Mail wird endgültig gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||||
"permanent_delete_confirm_batch_message": "Diese {count, plural, one {1 E-Mail} other {# E-Mails}} werden endgültig gelöscht. Diese Aktion kann nicht rückgängig gemacht werden."
|
"permanent_delete_confirm_batch_message": "Diese {count, plural, one {1 E-Mail} other {# E-Mails}} werden endgültig gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||||
|
"empty_folder": {
|
||||||
|
"button": "Ordner leeren",
|
||||||
|
"confirm_title": "Ordner leeren",
|
||||||
|
"confirm_message": "Alle E-Mails in diesem Ordner werden dauerhaft gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||||
|
"confirm_button": "Ordner leeren",
|
||||||
|
"junk_hint": "Sie können den Spam-Ordner leeren, um alle Nachrichten dauerhaft zu entfernen.",
|
||||||
|
"trash_hint": "Sie können den Papierkorb leeren, um alle Nachrichten dauerhaft zu entfernen."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"email_viewer": {
|
"email_viewer": {
|
||||||
"no_email_selected": "Keine E-Mail ausgewählt",
|
"no_email_selected": "Keine E-Mail ausgewählt",
|
||||||
@@ -594,6 +602,10 @@
|
|||||||
"permanent": "Dauerhaft löschen",
|
"permanent": "Dauerhaft löschen",
|
||||||
"warning": "E-Mails werden dauerhaft gelöscht und können nicht wiederhergestellt werden. Diese Aktion ist unwiderruflich."
|
"warning": "E-Mails werden dauerhaft gelöscht und können nicht wiederhergestellt werden. Diese Aktion ist unwiderruflich."
|
||||||
},
|
},
|
||||||
|
"permanently_delete_junk": {
|
||||||
|
"label": "Spam dauerhaft löschen",
|
||||||
|
"description": "E-Mails aus dem Spam-Ordner dauerhaft löschen, anstatt sie in den Papierkorb zu verschieben"
|
||||||
|
},
|
||||||
"show_preview": {
|
"show_preview": {
|
||||||
"label": "Vorschautext anzeigen",
|
"label": "Vorschautext anzeigen",
|
||||||
"description": "E-Mail-Vorschau in der Liste anzeigen"
|
"description": "E-Mail-Vorschau in der Liste anzeigen"
|
||||||
|
|||||||
+13
-1
@@ -130,7 +130,15 @@
|
|||||||
"permanent_delete": "Delete permanently",
|
"permanent_delete": "Delete permanently",
|
||||||
"permanent_delete_confirm_title": "Permanently delete",
|
"permanent_delete_confirm_title": "Permanently delete",
|
||||||
"permanent_delete_confirm_message": "This email will be permanently deleted. This action cannot be undone.",
|
"permanent_delete_confirm_message": "This email will be permanently deleted. This action cannot be undone.",
|
||||||
"permanent_delete_confirm_batch_message": "These {count, plural, one {1 email} other {# emails}} will be permanently deleted. This action cannot be undone."
|
"permanent_delete_confirm_batch_message": "These {count, plural, one {1 email} other {# emails}} will be permanently deleted. This action cannot be undone.",
|
||||||
|
"empty_folder": {
|
||||||
|
"button": "Empty folder",
|
||||||
|
"confirm_title": "Empty folder",
|
||||||
|
"confirm_message": "All emails in this folder will be permanently deleted. This action cannot be undone.",
|
||||||
|
"confirm_button": "Empty folder",
|
||||||
|
"junk_hint": "You can empty the Junk folder to permanently remove all messages.",
|
||||||
|
"trash_hint": "You can empty the Trash folder to permanently remove all messages."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"email_viewer": {
|
"email_viewer": {
|
||||||
"no_email_selected": "No email selected",
|
"no_email_selected": "No email selected",
|
||||||
@@ -598,6 +606,10 @@
|
|||||||
"permanent": "Delete Permanently",
|
"permanent": "Delete Permanently",
|
||||||
"warning": "Emails will be permanently deleted and cannot be recovered. This action is irreversible."
|
"warning": "Emails will be permanently deleted and cannot be recovered. This action is irreversible."
|
||||||
},
|
},
|
||||||
|
"permanently_delete_junk": {
|
||||||
|
"label": "Permanently Delete Junk",
|
||||||
|
"description": "Permanently delete emails from the Junk/Spam folder instead of moving them to Trash"
|
||||||
|
},
|
||||||
"show_preview": {
|
"show_preview": {
|
||||||
"label": "Show Preview Text",
|
"label": "Show Preview Text",
|
||||||
"description": "Display email preview in the list"
|
"description": "Display email preview in the list"
|
||||||
|
|||||||
+13
-1
@@ -130,7 +130,15 @@
|
|||||||
"permanent_delete": "Eliminar permanentemente",
|
"permanent_delete": "Eliminar permanentemente",
|
||||||
"permanent_delete_confirm_title": "Eliminar permanentemente",
|
"permanent_delete_confirm_title": "Eliminar permanentemente",
|
||||||
"permanent_delete_confirm_message": "Este correo se eliminará permanentemente. Esta acción no se puede deshacer.",
|
"permanent_delete_confirm_message": "Este correo se eliminará permanentemente. Esta acción no se puede deshacer.",
|
||||||
"permanent_delete_confirm_batch_message": "Estos {count, plural, one {1 correo} other {# correos}} se eliminarán permanentemente. Esta acción no se puede deshacer."
|
"permanent_delete_confirm_batch_message": "Estos {count, plural, one {1 correo} other {# correos}} se eliminarán permanentemente. Esta acción no se puede deshacer.",
|
||||||
|
"empty_folder": {
|
||||||
|
"button": "Vaciar carpeta",
|
||||||
|
"confirm_title": "Vaciar carpeta",
|
||||||
|
"confirm_message": "Todos los correos de esta carpeta se eliminarán permanentemente. Esta acción no se puede deshacer.",
|
||||||
|
"confirm_button": "Vaciar carpeta",
|
||||||
|
"junk_hint": "Puede vaciar la carpeta de Spam para eliminar permanentemente todos los mensajes.",
|
||||||
|
"trash_hint": "Puede vaciar la Papelera para eliminar permanentemente todos los mensajes."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"email_viewer": {
|
"email_viewer": {
|
||||||
"no_email_selected": "Ningún correo seleccionado",
|
"no_email_selected": "Ningún correo seleccionado",
|
||||||
@@ -594,6 +602,10 @@
|
|||||||
"permanent": "Eliminar Permanentemente",
|
"permanent": "Eliminar Permanentemente",
|
||||||
"warning": "Los correos se eliminarán permanentemente y no se podrán recuperar. Esta acción es irreversible."
|
"warning": "Los correos se eliminarán permanentemente y no se podrán recuperar. Esta acción es irreversible."
|
||||||
},
|
},
|
||||||
|
"permanently_delete_junk": {
|
||||||
|
"label": "Eliminar spam permanentemente",
|
||||||
|
"description": "Eliminar permanentemente los correos de la carpeta Spam en lugar de moverlos a la Papelera"
|
||||||
|
},
|
||||||
"show_preview": {
|
"show_preview": {
|
||||||
"label": "Mostrar Vista Previa",
|
"label": "Mostrar Vista Previa",
|
||||||
"description": "Mostrar vista previa del correo en la lista"
|
"description": "Mostrar vista previa del correo en la lista"
|
||||||
|
|||||||
+13
-1
@@ -130,7 +130,15 @@
|
|||||||
"permanent_delete": "Supprimer définitivement",
|
"permanent_delete": "Supprimer définitivement",
|
||||||
"permanent_delete_confirm_title": "Supprimer définitivement",
|
"permanent_delete_confirm_title": "Supprimer définitivement",
|
||||||
"permanent_delete_confirm_message": "Cet e-mail sera définitivement supprimé. Cette action est irréversible.",
|
"permanent_delete_confirm_message": "Cet e-mail sera définitivement supprimé. Cette action est irréversible.",
|
||||||
"permanent_delete_confirm_batch_message": "Ces {count, plural, one {1 e-mail} other {# e-mails}} seront définitivement supprimés. Cette action est irréversible."
|
"permanent_delete_confirm_batch_message": "Ces {count, plural, one {1 e-mail} other {# e-mails}} seront définitivement supprimés. Cette action est irréversible.",
|
||||||
|
"empty_folder": {
|
||||||
|
"button": "Vider le dossier",
|
||||||
|
"confirm_title": "Vider le dossier",
|
||||||
|
"confirm_message": "Tous les e-mails de ce dossier seront définitivement supprimés. Cette action est irréversible.",
|
||||||
|
"confirm_button": "Vider le dossier",
|
||||||
|
"junk_hint": "Vous pouvez vider le dossier Indésirables pour supprimer définitivement tous les messages.",
|
||||||
|
"trash_hint": "Vous pouvez vider la corbeille pour supprimer définitivement tous les messages."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"email_viewer": {
|
"email_viewer": {
|
||||||
"no_email_selected": "Aucun email sélectionné",
|
"no_email_selected": "Aucun email sélectionné",
|
||||||
@@ -594,6 +602,10 @@
|
|||||||
"permanent": "Supprimer définitivement",
|
"permanent": "Supprimer définitivement",
|
||||||
"warning": "Les emails seront supprimés définitivement et ne pourront pas être récupérés. Cette action est irréversible."
|
"warning": "Les emails seront supprimés définitivement et ne pourront pas être récupérés. Cette action est irréversible."
|
||||||
},
|
},
|
||||||
|
"permanently_delete_junk": {
|
||||||
|
"label": "Supprimer définitivement les indésirables",
|
||||||
|
"description": "Supprimer définitivement les e-mails du dossier Indésirables au lieu de les déplacer vers la corbeille"
|
||||||
|
},
|
||||||
"show_preview": {
|
"show_preview": {
|
||||||
"label": "Afficher l'aperçu",
|
"label": "Afficher l'aperçu",
|
||||||
"description": "Afficher l'aperçu de l'email dans la liste"
|
"description": "Afficher l'aperçu de l'email dans la liste"
|
||||||
|
|||||||
+13
-1
@@ -130,7 +130,15 @@
|
|||||||
"permanent_delete": "Elimina definitivamente",
|
"permanent_delete": "Elimina definitivamente",
|
||||||
"permanent_delete_confirm_title": "Elimina definitivamente",
|
"permanent_delete_confirm_title": "Elimina definitivamente",
|
||||||
"permanent_delete_confirm_message": "Questa e-mail verrà eliminata definitivamente. Questa azione non può essere annullata.",
|
"permanent_delete_confirm_message": "Questa e-mail verrà eliminata definitivamente. Questa azione non può essere annullata.",
|
||||||
"permanent_delete_confirm_batch_message": "Queste {count, plural, one {1 e-mail} other {# e-mail}} verranno eliminate definitivamente. Questa azione non può essere annullata."
|
"permanent_delete_confirm_batch_message": "Queste {count, plural, one {1 e-mail} other {# e-mail}} verranno eliminate definitivamente. Questa azione non può essere annullata.",
|
||||||
|
"empty_folder": {
|
||||||
|
"button": "Svuota cartella",
|
||||||
|
"confirm_title": "Svuota cartella",
|
||||||
|
"confirm_message": "Tutti i messaggi in questa cartella verranno eliminati definitivamente. Questa azione non può essere annullata.",
|
||||||
|
"confirm_button": "Svuota cartella",
|
||||||
|
"junk_hint": "Puoi svuotare la cartella Spam per rimuovere definitivamente tutti i messaggi.",
|
||||||
|
"trash_hint": "Puoi svuotare il Cestino per rimuovere definitivamente tutti i messaggi."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"email_viewer": {
|
"email_viewer": {
|
||||||
"no_email_selected": "Nessun messaggio selezionato",
|
"no_email_selected": "Nessun messaggio selezionato",
|
||||||
@@ -594,6 +602,10 @@
|
|||||||
"permanent": "Elimina definitivamente",
|
"permanent": "Elimina definitivamente",
|
||||||
"warning": "I messaggi verranno eliminati definitivamente e non potranno essere recuperati. Questa azione è irreversibile."
|
"warning": "I messaggi verranno eliminati definitivamente e non potranno essere recuperati. Questa azione è irreversibile."
|
||||||
},
|
},
|
||||||
|
"permanently_delete_junk": {
|
||||||
|
"label": "Elimina spam definitivamente",
|
||||||
|
"description": "Elimina definitivamente i messaggi dalla cartella Spam invece di spostarli nel cestino"
|
||||||
|
},
|
||||||
"show_preview": {
|
"show_preview": {
|
||||||
"label": "Mostra anteprima testo",
|
"label": "Mostra anteprima testo",
|
||||||
"description": "Visualizza l'anteprima del messaggio nell'elenco"
|
"description": "Visualizza l'anteprima del messaggio nell'elenco"
|
||||||
|
|||||||
+13
-1
@@ -130,7 +130,15 @@
|
|||||||
"permanent_delete": "完全に削除",
|
"permanent_delete": "完全に削除",
|
||||||
"permanent_delete_confirm_title": "完全に削除",
|
"permanent_delete_confirm_title": "完全に削除",
|
||||||
"permanent_delete_confirm_message": "このメールは完全に削除されます。この操作は取り消せません。",
|
"permanent_delete_confirm_message": "このメールは完全に削除されます。この操作は取り消せません。",
|
||||||
"permanent_delete_confirm_batch_message": "{count, plural, one {1件} other {#件}}のメールが完全に削除されます。この操作は取り消せません。"
|
"permanent_delete_confirm_batch_message": "{count, plural, one {1件} other {#件}}のメールが完全に削除されます。この操作は取り消せません。",
|
||||||
|
"empty_folder": {
|
||||||
|
"button": "フォルダを空にする",
|
||||||
|
"confirm_title": "フォルダを空にする",
|
||||||
|
"confirm_message": "このフォルダ内のすべてのメールが完全に削除されます。この操作は取り消せません。",
|
||||||
|
"confirm_button": "フォルダを空にする",
|
||||||
|
"junk_hint": "迷惑メールフォルダを空にして、すべてのメールを完全に削除できます。",
|
||||||
|
"trash_hint": "ゴミ箱を空にして、すべてのメールを完全に削除できます。"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"email_viewer": {
|
"email_viewer": {
|
||||||
"no_email_selected": "メールが選択されていません",
|
"no_email_selected": "メールが選択されていません",
|
||||||
@@ -594,6 +602,10 @@
|
|||||||
"permanent": "完全に削除",
|
"permanent": "完全に削除",
|
||||||
"warning": "メールは完全に削除され、復元できません。この操作は元に戻せません。"
|
"warning": "メールは完全に削除され、復元できません。この操作は元に戻せません。"
|
||||||
},
|
},
|
||||||
|
"permanently_delete_junk": {
|
||||||
|
"label": "迷惑メールを完全に削除",
|
||||||
|
"description": "迷惑メールフォルダのメールをゴミ箱に移動せずに完全に削除する"
|
||||||
|
},
|
||||||
"show_preview": {
|
"show_preview": {
|
||||||
"label": "プレビューテキストを表示",
|
"label": "プレビューテキストを表示",
|
||||||
"description": "リストにメールのプレビューを表示"
|
"description": "リストにメールのプレビューを表示"
|
||||||
|
|||||||
+13
-1
@@ -130,7 +130,15 @@
|
|||||||
"permanent_delete": "Definitief verwijderen",
|
"permanent_delete": "Definitief verwijderen",
|
||||||
"permanent_delete_confirm_title": "Definitief verwijderen",
|
"permanent_delete_confirm_title": "Definitief verwijderen",
|
||||||
"permanent_delete_confirm_message": "Deze e-mail wordt definitief verwijderd. Deze actie kan niet ongedaan worden gemaakt.",
|
"permanent_delete_confirm_message": "Deze e-mail wordt definitief verwijderd. Deze actie kan niet ongedaan worden gemaakt.",
|
||||||
"permanent_delete_confirm_batch_message": "Deze {count, plural, one {1 e-mail} other {# e-mails}} worden definitief verwijderd. Deze actie kan niet ongedaan worden gemaakt."
|
"permanent_delete_confirm_batch_message": "Deze {count, plural, one {1 e-mail} other {# e-mails}} worden definitief verwijderd. Deze actie kan niet ongedaan worden gemaakt.",
|
||||||
|
"empty_folder": {
|
||||||
|
"button": "Map legen",
|
||||||
|
"confirm_title": "Map legen",
|
||||||
|
"confirm_message": "Alle e-mails in deze map worden permanent verwijderd. Deze actie kan niet ongedaan worden gemaakt.",
|
||||||
|
"confirm_button": "Map legen",
|
||||||
|
"junk_hint": "U kunt de map Spam legen om alle berichten permanent te verwijderen.",
|
||||||
|
"trash_hint": "U kunt de prullenbak legen om alle berichten permanent te verwijderen."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"email_viewer": {
|
"email_viewer": {
|
||||||
"no_email_selected": "Geen e-mail geselecteerd",
|
"no_email_selected": "Geen e-mail geselecteerd",
|
||||||
@@ -594,6 +602,10 @@
|
|||||||
"permanent": "Permanent verwijderen",
|
"permanent": "Permanent verwijderen",
|
||||||
"warning": "E-mails worden permanent verwijderd en kunnen niet worden hersteld. Deze actie is onomkeerbaar."
|
"warning": "E-mails worden permanent verwijderd en kunnen niet worden hersteld. Deze actie is onomkeerbaar."
|
||||||
},
|
},
|
||||||
|
"permanently_delete_junk": {
|
||||||
|
"label": "Spam permanent verwijderen",
|
||||||
|
"description": "E-mails uit de map Spam permanent verwijderen in plaats van naar de prullenbak te verplaatsen"
|
||||||
|
},
|
||||||
"show_preview": {
|
"show_preview": {
|
||||||
"label": "Voorbeeldtekst tonen",
|
"label": "Voorbeeldtekst tonen",
|
||||||
"description": "E-mailvoorbeeld weergeven in de lijst"
|
"description": "E-mailvoorbeeld weergeven in de lijst"
|
||||||
|
|||||||
+13
-1
@@ -130,7 +130,15 @@
|
|||||||
"permanent_delete": "Excluir permanentemente",
|
"permanent_delete": "Excluir permanentemente",
|
||||||
"permanent_delete_confirm_title": "Excluir permanentemente",
|
"permanent_delete_confirm_title": "Excluir permanentemente",
|
||||||
"permanent_delete_confirm_message": "Este e-mail será permanentemente excluído. Esta ação não pode ser desfeita.",
|
"permanent_delete_confirm_message": "Este e-mail será permanentemente excluído. Esta ação não pode ser desfeita.",
|
||||||
"permanent_delete_confirm_batch_message": "Estes {count, plural, one {1 e-mail} other {# e-mails}} serão permanentemente excluídos. Esta ação não pode ser desfeita."
|
"permanent_delete_confirm_batch_message": "Estes {count, plural, one {1 e-mail} other {# e-mails}} serão permanentemente excluídos. Esta ação não pode ser desfeita.",
|
||||||
|
"empty_folder": {
|
||||||
|
"button": "Esvaziar pasta",
|
||||||
|
"confirm_title": "Esvaziar pasta",
|
||||||
|
"confirm_message": "Todos os e-mails nesta pasta serão permanentemente excluídos. Esta ação não pode ser desfeita.",
|
||||||
|
"confirm_button": "Esvaziar pasta",
|
||||||
|
"junk_hint": "Você pode esvaziar a pasta de Spam para remover permanentemente todas as mensagens.",
|
||||||
|
"trash_hint": "Você pode esvaziar a Lixeira para remover permanentemente todas as mensagens."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"email_viewer": {
|
"email_viewer": {
|
||||||
"no_email_selected": "Nenhum e-mail selecionado",
|
"no_email_selected": "Nenhum e-mail selecionado",
|
||||||
@@ -594,6 +602,10 @@
|
|||||||
"permanent": "Excluir Permanentemente",
|
"permanent": "Excluir Permanentemente",
|
||||||
"warning": "Os e-mails serão excluídos permanentemente e não poderão ser recuperados. Esta ação é irreversível."
|
"warning": "Os e-mails serão excluídos permanentemente e não poderão ser recuperados. Esta ação é irreversível."
|
||||||
},
|
},
|
||||||
|
"permanently_delete_junk": {
|
||||||
|
"label": "Excluir spam permanentemente",
|
||||||
|
"description": "Excluir permanentemente e-mails da pasta Spam em vez de movê-los para a Lixeira"
|
||||||
|
},
|
||||||
"show_preview": {
|
"show_preview": {
|
||||||
"label": "Mostrar Texto de Visualização",
|
"label": "Mostrar Texto de Visualização",
|
||||||
"description": "Exibir visualização do e-mail na lista"
|
"description": "Exibir visualização do e-mail na lista"
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ interface EmailStore {
|
|||||||
renameMailbox: (client: JMAPClient, mailboxId: string, name: string) => Promise<void>;
|
renameMailbox: (client: JMAPClient, mailboxId: string, name: string) => Promise<void>;
|
||||||
deleteMailbox: (client: JMAPClient, mailboxId: string) => Promise<void>;
|
deleteMailbox: (client: JMAPClient, mailboxId: string) => Promise<void>;
|
||||||
setMailboxRole: (client: JMAPClient, mailboxId: string, role: string | null) => Promise<void>;
|
setMailboxRole: (client: JMAPClient, mailboxId: string, role: string | null) => Promise<void>;
|
||||||
|
emptyMailbox: (client: JMAPClient, mailboxId: string) => Promise<void>;
|
||||||
|
|
||||||
// Mock data for demo
|
// Mock data for demo
|
||||||
loadMockData: () => void;
|
loadMockData: () => void;
|
||||||
@@ -411,6 +412,7 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
|
|||||||
|
|
||||||
// Get delete action preference from settings
|
// Get delete action preference from settings
|
||||||
const deleteAction = useSettingsStore.getState().deleteAction;
|
const deleteAction = useSettingsStore.getState().deleteAction;
|
||||||
|
const permanentlyDeleteJunk = useSettingsStore.getState().permanentlyDeleteJunk;
|
||||||
|
|
||||||
// Determine accountId for shared folders
|
// Determine accountId for shared folders
|
||||||
const selectedMailboxId = get().selectedMailbox;
|
const selectedMailboxId = get().selectedMailbox;
|
||||||
@@ -418,6 +420,12 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
|
|||||||
const currentMailbox = mailboxes.find(mb => mb.id === selectedMailboxId);
|
const currentMailbox = mailboxes.find(mb => mb.id === selectedMailboxId);
|
||||||
const accountId = currentMailbox?.isShared ? currentMailbox.accountId : undefined;
|
const accountId = currentMailbox?.isShared ? currentMailbox.accountId : undefined;
|
||||||
|
|
||||||
|
// If in junk folder and setting is enabled, permanently delete
|
||||||
|
const isInJunk = currentMailbox?.role === 'junk';
|
||||||
|
if (isInJunk && permanentlyDeleteJunk) {
|
||||||
|
forceDelete = true;
|
||||||
|
}
|
||||||
|
|
||||||
// If deleteAction is 'trash' and not forced permanent delete, try to move to trash mailbox
|
// If deleteAction is 'trash' and not forced permanent delete, try to move to trash mailbox
|
||||||
if (deleteAction === 'trash' && !forceDelete) {
|
if (deleteAction === 'trash' && !forceDelete) {
|
||||||
// Find trash mailbox for the correct account
|
// Find trash mailbox for the correct account
|
||||||
@@ -1287,6 +1295,35 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
emptyMailbox: async (client, mailboxId) => {
|
||||||
|
try {
|
||||||
|
set({ isLoading: true, error: null });
|
||||||
|
await client.emptyMailbox(mailboxId);
|
||||||
|
|
||||||
|
// Clear emails from local state if we're viewing this mailbox
|
||||||
|
const currentMailbox = get().selectedMailbox;
|
||||||
|
if (currentMailbox === mailboxId) {
|
||||||
|
set({ emails: [], selectedEmail: null });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update mailbox counters
|
||||||
|
set({
|
||||||
|
mailboxes: get().mailboxes.map(mb =>
|
||||||
|
mb.id === mailboxId
|
||||||
|
? { ...mb, totalEmails: 0, unreadEmails: 0, totalThreads: 0, unreadThreads: 0 }
|
||||||
|
: mb
|
||||||
|
),
|
||||||
|
isLoading: false,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
set({
|
||||||
|
error: error instanceof Error ? error.message : 'Failed to empty folder',
|
||||||
|
isLoading: false,
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
loadMockData: () => {
|
loadMockData: () => {
|
||||||
const mockEmails: Email[] = [
|
const mockEmails: Email[] = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ interface SettingsState {
|
|||||||
// Email Behavior
|
// Email Behavior
|
||||||
markAsReadDelay: number; // milliseconds (0 = instant, -1 = never)
|
markAsReadDelay: number; // milliseconds (0 = instant, -1 = never)
|
||||||
deleteAction: DeleteAction;
|
deleteAction: DeleteAction;
|
||||||
|
permanentlyDeleteJunk: boolean; // Permanently delete emails from junk/spam instead of moving to trash
|
||||||
showPreview: boolean;
|
showPreview: boolean;
|
||||||
emailsPerPage: number;
|
emailsPerPage: number;
|
||||||
externalContentPolicy: ExternalContentPolicy;
|
externalContentPolicy: ExternalContentPolicy;
|
||||||
@@ -154,6 +155,7 @@ const DEFAULT_SETTINGS = {
|
|||||||
// Email Behavior
|
// Email Behavior
|
||||||
markAsReadDelay: 0, // Instant
|
markAsReadDelay: 0, // Instant
|
||||||
deleteAction: 'trash' as DeleteAction,
|
deleteAction: 'trash' as DeleteAction,
|
||||||
|
permanentlyDeleteJunk: false,
|
||||||
showPreview: true,
|
showPreview: true,
|
||||||
emailsPerPage: 50,
|
emailsPerPage: 50,
|
||||||
externalContentPolicy: 'ask' as ExternalContentPolicy,
|
externalContentPolicy: 'ask' as ExternalContentPolicy,
|
||||||
|
|||||||
Reference in New Issue
Block a user