diff --git a/apps/web/src/lib/api-types.ts b/apps/web/src/lib/api-types.ts index 53b5609..111de41 100644 --- a/apps/web/src/lib/api-types.ts +++ b/apps/web/src/lib/api-types.ts @@ -59,11 +59,9 @@ export type Alias = { id: string; domainId: string; source: string; destination: export type MailFolder = { id: string; name: string; role: string; unreadCount: number; totalCount: number; uidValidity: number; uidNext: number; highestModseq: number } export type Attachment = { id: string; messageId: string; filename: string; contentType: string; sizeBytes: number; createdAt: string } export type MailLabel = { id: string; mailboxId?: string; name: string; color: string; messageCount?: number } -export type MailAuthentication = { authenticationResults: string; receivedSpf: string; spf: string; dkim: string; dmarc: string } export type MailMessage = { id: string; mailboxId?: string; mailboxAddress?: string; ownerEmail?: string; recipientAddress?: string; folderId: string; folder: string; messageUid: string; imapUid: number; imapModseq: number; messageId: string; subject: string; from: string; fromName?: string; to: string[]; cc: string[]; bcc?: string[]; sentAt: string; receivedAt: string; snippet: string; bodyText?: string; bodyHtml?: string; isRead: boolean; isStarred: boolean; hasAttachments: boolean; sizeBytes: number; attachments?: Attachment[] labels?: MailLabel[] - authentication?: MailAuthentication } export type DNSRecord = { type: string; name: string; value: string; ttl: number } export type DNSCheckResult = { domain: string; status: string; checks: Record } diff --git a/apps/web/src/pages/mail.tsx b/apps/web/src/pages/mail.tsx index 15bf15c..0542786 100644 --- a/apps/web/src/pages/mail.tsx +++ b/apps/web/src/pages/mail.tsx @@ -394,7 +394,24 @@ export function MailPage() { const firstSender = senderDisplayName(first) const title = newMessages.length > 1 ? `收到 ${newMessages.length} 封新邮件` : `新邮件:${first.subject || "(无主题)"}` const description = newMessages.length > 1 ? `${firstSender} 等发来新邮件` : `${firstSender}${first.snippet ? ` · ${first.snippet}` : ""}` - toast({ title, description }) + const openFirstMessage = () => { + setMailView("folder") + setFolder("Inbox") + setSelectedId(first.id) + } + toast({ + title, + description, + onClick: openFirstMessage, + onKeyDown: (event) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault() + openFirstMessage() + } + }, + role: "button", + tabIndex: 0, + }) playIncomingMailSound(mailAudioContextRef) if ("Notification" in window && Notification.permission === "granted") { const notification = new Notification(title, { @@ -403,9 +420,7 @@ export function MailPage() { }) notification.onclick = () => { window.focus() - setMailView("folder") - setFolder("Inbox") - setSelectedId(first.id) + openFirstMessage() notification.close() } } @@ -1963,7 +1978,6 @@ function MessageMetaPanel({ message, availableLabels, onAddLabel, onRemoveLabel, {formatDateTime(message.receivedAt)} - {availableLabels && onAddLabel && onRemoveLabel && (
@@ -2025,41 +2039,6 @@ function MessageMetaPanel({ message, availableLabels, onAddLabel, onRemoveLabel, ) } -function AuthenticationResultRow({ message }: { message: MailMessage }) { - const auth = message.authentication || { authenticationResults: "", receivedSpf: "", spf: "unknown", dkim: "unknown", dmarc: "unknown" } - const title = [auth.authenticationResults, auth.receivedSpf].filter(Boolean).join("\n\n") - return ( - -
- - - -
-
- ) -} - -function AuthStatusBadge({ label, value }: { label: string; value?: string }) { - const status = normalizeAuthStatus(value) - return ( - - {label}:{status} - - ) -} - -function normalizeAuthStatus(value?: string) { - const status = (value || "").trim().toLowerCase() - if (["pass", "fail", "softfail", "neutral", "temperror", "permerror", "none"].includes(status)) return status - return "unknown" -} - -function authStatusClassName(status: string) { - if (status === "pass") return "border-emerald-300 bg-emerald-50 text-emerald-700" - if (["fail", "softfail", "permerror"].includes(status)) return "border-red-300 bg-red-50 text-red-700" - return "border-slate-300 bg-slate-50 text-slate-600" -} - function MessageMetaRow({ label, children }: { label: string; children: React.ReactNode }) { return (