ultisuite-client/components/gmail/email-list/list-mail-index.ts
2026-05-20 18:22:36 +02:00

50 lines
1.4 KiB
TypeScript

"use client"
import { useCallback } from "react"
import type { Email } from "@/lib/email-data"
import { useMailStore } from "@/lib/stores/mail-store"
export type ListMailIndex = {
emailById: Map<string, Email>
scheduledIds: Set<string>
}
/** O(n) index for list row logic — avoids repeated `allEmails.some` / `find` per row. */
export function buildListMailIndex(emails: Email[]): ListMailIndex {
const emailById = new Map<string, Email>()
const scheduledIds = new Set<string>()
for (const e of emails) {
emailById.set(e.id, e)
if (e.labels?.includes("scheduled")) scheduledIds.add(e.id)
}
return { emailById, scheduledIds }
}
export type MailRowFlags = {
isRead: boolean
isStarred: boolean
isImportant: boolean
}
/**
* Per-row mail UI flags from the persisted mail store.
* Use inside a keyed `memo` row component (not a plain `.map` callback).
*/
export function useMailRowFlags(email: Email): MailRowFlags {
const id = email.id
const readOverride = useMailStore(
useCallback((s) => s.readOverrides[id], [id])
)
const starred = useMailStore(
useCallback((s) => s.starredIds.includes(id), [id])
)
const important = useMailStore(
useCallback((s) => s.importantIds.includes(id), [id])
)
return {
isRead: readOverride !== undefined ? readOverride : email.read,
isStarred: starred || email.starred,
isImportant: important || email.important,
}
}