diff --git a/frontend/src/components/mail/MailList.tsx b/frontend/src/components/mail/MailList.tsx index dc57a55..32ae8ae 100644 --- a/frontend/src/components/mail/MailList.tsx +++ b/frontend/src/components/mail/MailList.tsx @@ -1,17 +1,15 @@ /** - * Mail list component with pagination and virtual scrolling. - * Shows list of mails in selected folder with seen/flagged indicators. + * Mail list component with infinite scroll. + * No pagination, no sort header — sorting is in toolbar SortPanel. */ -import React, { useRef } from 'react'; +import React, { useRef, useEffect } from 'react'; import clsx from 'clsx'; import { useTranslation } from 'react-i18next'; -import { useVirtualizer } from '@tanstack/react-virtual'; import type { Mail } from '@/api/mail'; import { decodeMimeHeader } from '@/api/mail'; import { EmptyState } from '@/components/ui/EmptyState'; -import { Pagination } from '@/components/ui/Pagination'; -import { ChevronUp, Loader2, Paperclip, Star } from 'lucide-react'; +import { Loader2, Paperclip, Star } from 'lucide-react'; import { formatSmartDate } from '@/utils/date'; export interface MailListProps { @@ -19,16 +17,11 @@ export interface MailListProps { selectedMailId: string | null; onSelectMail: (mail: Mail) => void; loading: boolean; - currentPage: number; - total: number; - pageSize: number; - onPageChange: (page: number) => void; selectedMailIds: Set; onToggleSelect: (mailId: string) => void; onSelectAll: () => void; - sortBy?: 'date' | 'from' | 'subject'; - sortOrder?: 'asc' | 'desc'; - onSortChange?: (sortBy: 'date' | 'from' | 'subject', sortOrder: 'asc' | 'desc') => void; + onLoadMore?: () => void; + hasMore?: boolean; } function formatDate(dateStr: string): string { @@ -40,44 +33,25 @@ export function MailList({ selectedMailId, onSelectMail, loading, - currentPage, - total, - pageSize, - onPageChange, selectedMailIds, onToggleSelect, onSelectAll, - sortBy = 'date', - sortOrder = 'desc', - onSortChange, + onLoadMore, + hasMore = false, }: MailListProps) { const { t } = useTranslation(); - const totalPages = Math.ceil(total / pageSize); const allSelected = mails.length > 0 && mails.every((m) => selectedMailIds.has(m.id)); const scrollRef = useRef(null); - // Auto-skip virtualization for small datasets - const shouldVirtualize = mails.length >= 50; - - const rowVirtualizer = useVirtualizer({ - count: shouldVirtualize ? mails.length : 0, - getScrollElement: () => scrollRef.current, - estimateSize: () => 80, // approx mail item height - overscan: 8, - enabled: shouldVirtualize, - }); - - const handleSortFieldChange = (e: React.ChangeEvent) => { - const newSortBy = e.target.value as 'date' | 'from' | 'subject'; - onSortChange?.(newSortBy, sortOrder); + // Infinite scroll handler + const handleScroll = (e: React.UIEvent) => { + const el = e.currentTarget; + if (el.scrollTop + el.clientHeight >= el.scrollHeight - 200 && onLoadMore && !loading && hasMore) { + onLoadMore(); + } }; - const handleSortOrderToggle = () => { - const newOrder = sortOrder === 'asc' ? 'desc' : 'asc'; - onSortChange?.(sortBy, newOrder); - }; - - if (loading) { + if (loading && mails.length === 0) { return (