diff --git a/frontend/pages/email/index.vue b/frontend/pages/email/index.vue index 0046dad..496ae0e 100644 --- a/frontend/pages/email/index.vue +++ b/frontend/pages/email/index.vue @@ -70,6 +70,7 @@ const loadingMessages = ref(false) const loadingMessage = ref(false) const syncing = ref(false) const expandedMailboxPaths = ref([]) +const syncedMailboxPaths = ref([]) const selectedAccount = computed(() => accounts.value.find((account) => account.id === selectedAccountId.value) || null @@ -294,6 +295,7 @@ async function loadAccounts() { async function loadMailboxes() { if (!selectedAccountId.value) return + const previousMailboxPath = selectedMailboxPath.value loadingMailboxes.value = true selectedMessage.value = null @@ -301,7 +303,8 @@ async function loadMailboxes() { mailboxes.value = await $api(`/api/email/accounts/${selectedAccountId.value}/mailboxes`) resetExpandedMailboxes() const inbox = mailboxes.value.find((mailbox) => mailbox.specialUse === "\\Inbox" || mailbox.path.toUpperCase() === "INBOX") - selectedMailboxPath.value = inbox?.path || mailboxes.value[0]?.path || "INBOX" + const previousMailbox = mailboxes.value.find((mailbox) => mailbox.path === previousMailboxPath) + selectedMailboxPath.value = previousMailbox?.path || inbox?.path || mailboxes.value[0]?.path || "INBOX" expandMailboxAncestors(selectedMailboxPath.value) await loadMessages() } finally { @@ -309,19 +312,20 @@ async function loadMailboxes() { } } -async function loadMessages() { +async function loadMessages(options: { syncIfEmpty?: boolean } = {}) { if (!selectedAccountId.value || !selectedMailboxPath.value) return loadingMessages.value = true selectedMessage.value = null try { - messages.value = await $api(`/api/email/accounts/${selectedAccountId.value}/messages`, { - query: { - mailbox: selectedMailboxPath.value, - limit: 100, - }, - }) + messages.value = await fetchMessages(selectedMailboxPath.value) + + if (!messages.value.length && options.syncIfEmpty && !syncedMailboxPaths.value.includes(selectedMailboxPath.value)) { + await syncSelectedMailbox({ silent: true, reloadMailboxes: false }) + syncedMailboxPaths.value = [...syncedMailboxPaths.value, selectedMailboxPath.value] + messages.value = await fetchMessages(selectedMailboxPath.value) + } if (messages.value.length) { await selectMessage(messages.value[0]) @@ -331,10 +335,19 @@ async function loadMessages() { } } +async function fetchMessages(mailboxPath: string) { + return await $api(`/api/email/accounts/${selectedAccountId.value}/messages`, { + query: { + mailbox: mailboxPath, + limit: 100, + }, + }) +} + async function selectMailbox(mailbox: EmailMailbox) { selectedMailboxPath.value = mailbox.path expandMailboxAncestors(mailbox.path) - await loadMessages() + await loadMessages({ syncIfEmpty: true }) } async function selectMessage(message: EmailMessage) { @@ -384,6 +397,10 @@ async function setMessageSeen(messageId: string, seen: boolean) { async function syncAccount() { if (!selectedAccountId.value) return + await syncSelectedMailbox({ silent: false, reloadMailboxes: true }) +} + +async function syncSelectedMailbox(options: { silent: boolean; reloadMailboxes: boolean }) { syncing.value = true try { const res = await $api(`/api/email/accounts/${selectedAccountId.value}/sync`, { @@ -394,19 +411,25 @@ async function syncAccount() { }, }) - toast.add({ - title: "E-Mails synchronisiert", - description: `${res.synced?.[0]?.fetched || 0} neue Nachrichten geladen`, - color: "success", - }) + if (!options.silent) { + toast.add({ + title: "E-Mails synchronisiert", + description: `${res.synced?.[0]?.fetched || 0} neue Nachrichten geladen`, + color: "success", + }) + } - await loadMailboxes() + if (options.reloadMailboxes) { + await loadMailboxes() + } } catch (err: any) { - toast.add({ - title: "Synchronisation fehlgeschlagen", - description: err?.data?.error || err?.message || "Das Postfach konnte nicht synchronisiert werden.", - color: "error", - }) + if (!options.silent) { + toast.add({ + title: "Synchronisation fehlgeschlagen", + description: err?.data?.error || err?.message || "Das Postfach konnte nicht synchronisiert werden.", + color: "error", + }) + } } finally { syncing.value = false }