"use client"; import { useCallback } from "react"; import { useTranslations } from "next-intl"; import { formatDate } from "@/lib/utils"; import { Email } from "@/lib/jmap/types"; import { cn } from "@/lib/utils"; import { Avatar } from "@/components/ui/avatar"; import { Paperclip, Star, Circle, CheckSquare, Square, Reply, Forward } from "lucide-react"; import { useEmailDrag } from "@/hooks/use-email-drag"; import { useLongPress } from "@/hooks/use-long-press"; import { useEmailStore } from "@/stores/email-store"; import { useSettingsStore } from "@/stores/settings-store"; import { useUIStore } from "@/stores/ui-store"; interface ThreadEmailItemProps { email: Email; selected?: boolean; isLast?: boolean; onClick?: () => void; onDoubleClick?: () => void; onContextMenu?: (e: React.MouseEvent, email: Email) => void; } export function ThreadEmailItem({ email, selected, isLast = false, onClick, onDoubleClick, onContextMenu, }: ThreadEmailItemProps) { const t = useTranslations('email_viewer'); const isUnread = !email.keywords?.$seen; const isStarred = email.keywords?.$flagged; const isAnswered = email.keywords?.$answered; const isForwarded = email.keywords?.$forwarded; const sender = email.from?.[0]; const { selectedMailbox, selectedEmailIds, toggleEmailSelection, selectRangeEmails, clearSelection } = useEmailStore(); const density = useSettingsStore((state) => state.density); const isChecked = selectedEmailIds.has(email.id); const { dragHandlers, isDragging } = useEmailDrag({ email, sourceMailboxId: selectedMailbox, }); const isMobile = useUIStore((state) => state.isMobile); const { onTouchStart, onTouchEnd, onTouchMove, onTouchCancel, isPressed } = useLongPress( useCallback((pos) => { onContextMenu?.( { preventDefault: () => {}, stopPropagation: () => {}, clientX: pos.clientX, clientY: pos.clientY } as React.MouseEvent, email ); }, [onContextMenu, email]), isMobile ); const longPressHandlers = { onTouchStart, onTouchEnd, onTouchMove, onTouchCancel }; const handleContextMenu = (e: React.MouseEvent) => { onContextMenu?.(e, email); }; const handleCheckboxClick = (e: React.MouseEvent) => { e.stopPropagation(); toggleEmailSelection(email.id); }; const handleClick = (e: React.MouseEvent) => { if (e.ctrlKey || e.metaKey) { e.preventDefault(); toggleEmailSelection(email.id); } else if (e.shiftKey) { e.preventDefault(); selectRangeEmails(email.id); } else { if (selectedEmailIds.size > 0) clearSelection(); onClick?.(); } }; return (
{ if (e.ctrlKey || e.metaKey || e.shiftKey) return; if (!onDoubleClick) return; e.preventDefault(); onDoubleClick(); }} onContextMenu={handleContextMenu} style={{ paddingBlock: 'var(--density-item-py)' }} >
{/* Checkbox - only visible when in selection mode */} {selectedEmailIds.size > 0 && ( )} {/* Unread indicator */} {isUnread && (
)} {/* Small Avatar */} {density !== 'extra-compact' && ( )} {/* Content */}
{/* Single line: Sender, indicators, preview, date */}
{sender?.name || sender?.email?.split('@')[0] || "Unknown"} {/* Indicators */}
{isStarred && ( )} {isAnswered && !isForwarded && ( )} {isForwarded && !isAnswered && ( )} {isAnswered && isForwarded && ( <> )} {email.hasAttachment && ( )}
{/* Preview snippet */} {email.preview || t('no_preview_available')} {/* Date */} {formatDate(email.receivedAt)}
); }