Some checks failed
E2E / Playwright e2e (push) Has been cancelled
Move mail, compose, contacts, and accounts off mocks onto REST + WS. Add client, auth store, IDB-backed query cache, offline queue, and sync bar; hybrid Zustand for UI-only state. Settings still local until backend has preferences API.
89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
"use client"
|
|
|
|
import { useMemo } from "react"
|
|
import { mailLabelShouldShowInListStrip } from "@/components/gmail/mail-label-pills"
|
|
import { EmailView } from "@/components/gmail/email-view"
|
|
import { LABEL_PICKER_EXCLUDE } from "@/lib/mail-list/label-actions"
|
|
import type { Email } from "@/lib/email-data"
|
|
import type { ApiMessageSummary } from "@/lib/api/types"
|
|
import type { EmailListData } from "@/components/gmail/email-list/hooks/use-email-list-data"
|
|
import type { EmailListReading } from "@/components/gmail/email-list/hooks/use-email-list-reading"
|
|
import type { EmailListSelection } from "@/components/gmail/email-list/hooks/use-email-list-selection"
|
|
|
|
function emailToApiSummary(email: Email): ApiMessageSummary {
|
|
const flags: string[] = []
|
|
if (email.read) flags.push("read")
|
|
if (email.starred) flags.push("starred")
|
|
if (email.important) flags.push("important")
|
|
if (email.spam) flags.push("spam")
|
|
return {
|
|
id: email.id,
|
|
message_id: email.id,
|
|
thread_id: email.threadHeadId,
|
|
account_id: "",
|
|
subject: email.subject,
|
|
from: [{ name: email.sender, address: email.senderEmail ?? "" }],
|
|
to: [],
|
|
date: email.date,
|
|
snippet: email.preview,
|
|
flags,
|
|
labels: email.labels ?? [],
|
|
has_attachments: email.hasAttachment ?? false,
|
|
}
|
|
}
|
|
|
|
type EmailListEmailViewPaneProps = {
|
|
data: EmailListData
|
|
reading: EmailListReading
|
|
selection: EmailListSelection
|
|
}
|
|
|
|
export function EmailListEmailViewPane({
|
|
data,
|
|
reading,
|
|
selection: _selection,
|
|
}: EmailListEmailViewPaneProps) {
|
|
const {
|
|
openEmail,
|
|
isSingleMessageView,
|
|
handleNavigateToLabel,
|
|
} = reading
|
|
const {
|
|
listRowLabelBgByTextLower,
|
|
sidebarNav,
|
|
selectedFolder,
|
|
} = data
|
|
|
|
const apiEmail = useMemo(
|
|
() => (openEmail ? emailToApiSummary(openEmail) : null),
|
|
[openEmail]
|
|
)
|
|
|
|
if (!openEmail || !apiEmail) return null
|
|
|
|
return (
|
|
<EmailView
|
|
email={apiEmail}
|
|
isSingleMessageView={isSingleMessageView}
|
|
onNavigateToLabel={handleNavigateToLabel}
|
|
labelBgByText={listRowLabelBgByTextLower}
|
|
emailLabelToSidebarFolderId={sidebarNav.emailLabelToSidebarFolderId}
|
|
getNavItemPrefs={sidebarNav.getNavItemPrefs}
|
|
folderTree={sidebarNav.folderTree}
|
|
labelRows={sidebarNav.labelRows}
|
|
currentFolderId={selectedFolder}
|
|
showLabelChip={(lab) => {
|
|
if (LABEL_PICKER_EXCLUDE.has(lab)) return true
|
|
return mailLabelShouldShowInListStrip(
|
|
lab,
|
|
sidebarNav.emailLabelToSidebarFolderId,
|
|
sidebarNav.getNavItemPrefs,
|
|
sidebarNav.labelRows
|
|
)
|
|
}}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export type { EmailListEmailViewPaneProps }
|