From 2ee601031cdecbbba980ba3ea2a36e64d19e7f71 Mon Sep 17 00:00:00 2001 From: Aj Wazzan Date: Mon, 28 Apr 2025 13:34:53 -0700 Subject: [PATCH] Refactor mail components to include labels in thread data and improve layout structure. Updated type definitions and adjusted state management in MailDisplay and MailList components for better handling of email labels. --- apps/mail/app/(routes)/layout.tsx | 4 ++-- apps/mail/app/api/driver/google.ts | 22 ++++++++++++++++++---- apps/mail/app/api/driver/types.ts | 1 + apps/mail/components/mail/mail-display.tsx | 10 ++++++---- apps/mail/components/mail/mail-list.tsx | 21 ++++++++++++--------- apps/mail/hooks/use-threads.ts | 10 +++++++++- apps/mail/lib/email-utils.ts | 2 +- 7 files changed, 49 insertions(+), 21 deletions(-) diff --git a/apps/mail/app/(routes)/layout.tsx b/apps/mail/app/(routes)/layout.tsx index 233e9fb14..948b7ef2b 100644 --- a/apps/mail/app/(routes)/layout.tsx +++ b/apps/mail/app/(routes)/layout.tsx @@ -9,10 +9,10 @@ export default function Layout({ children }: { children: React.ReactNode }) { return ( -
+
=> { }); if (!res.data.messages) - return { messages: [], latest: undefined, hasUnread: false, totalReplies: 0 }; + return { + messages: [], + latest: undefined, + hasUnread: false, + totalReplies: 0, + labels: [], + }; let hasUnread = false; + const labels = new Set(); const messages: ParsedMessage[] = await Promise.all( res.data.messages.map(async (message) => { const bodyData = @@ -725,6 +730,14 @@ export const driver = async (config: IConfig): Promise => { } const parsedData = parse(message); + if (parsedData.tags) { + parsedData.tags.forEach((tag) => { + if (tag.id) { + if (labels.has(tag.id)) return; + labels.add(tag.id); + } + }); + } const attachments = await Promise.all( message.payload?.parts @@ -787,6 +800,7 @@ export const driver = async (config: IConfig): Promise => { }), ); return { + labels: Array.from(labels).map((id) => ({ id, name: id })), messages, latest: messages[messages.length - 1], hasUnread, diff --git a/apps/mail/app/api/driver/types.ts b/apps/mail/app/api/driver/types.ts index 359e1d33c..78c147451 100644 --- a/apps/mail/app/api/driver/types.ts +++ b/apps/mail/app/api/driver/types.ts @@ -6,6 +6,7 @@ export interface IGetThreadResponse { latest: ParsedMessage | undefined; hasUnread: boolean; totalReplies: number; + labels: { id: string; name: string }[]; } export interface ParsedDraft { diff --git a/apps/mail/components/mail/mail-display.tsx b/apps/mail/components/mail/mail-display.tsx index bd5596359..7be19ce9f 100644 --- a/apps/mail/components/mail/mail-display.tsx +++ b/apps/mail/components/mail/mail-display.tsx @@ -286,12 +286,14 @@ const MailDisplay = ({ emailData, index, totalEmails, demo }: Props) => { const t = useTranslations(); const [activeReplyId, setActiveReplyId] = useQueryState('activeReplyId'); - console.warn(emailData, 'emailData'); - useEffect(() => { if (!demo) { + if (activeReplyId === emailData.id) { + setIsCollapsed(false); + } else { + setIsCollapsed(activeReplyId ? true : totalEmails ? index !== totalEmails - 1 : false); + } // Set all emails to collapsed by default except the last one - setIsCollapsed(totalEmails ? index !== totalEmails - 1 : false); if (totalEmails && index === totalEmails - 1) { if (totalEmails > 5) { setTimeout(() => { @@ -301,7 +303,7 @@ const MailDisplay = ({ emailData, index, totalEmails, demo }: Props) => { } } } - }, [index, emailData.id, totalEmails, demo]); + }, [index, activeReplyId, emailData.id, totalEmails, demo]); const listUnsubscribeAction = useMemo( () => diff --git a/apps/mail/components/mail/mail-list.tsx b/apps/mail/components/mail/mail-list.tsx index 7ddbf5d5a..0a77f2991 100644 --- a/apps/mail/components/mail/mail-list.tsx +++ b/apps/mail/components/mail/mail-list.tsx @@ -149,14 +149,17 @@ const Thread = memo( const hoverTimeoutRef = useRef | undefined>(undefined); const isHovering = useRef(false); const hasPrefetched = useRef(false); - const { data: getThreadData, isLoading, isGroupThread } = useThread(demo ? null : message.id); + const { + data: getThreadData, + labels, + isLoading, + isGroupThread, + } = useThread(demo ? null : message.id); const latestMessage = demo ? demoMessage : getThreadData?.latest; const emailContent = demo ? demoMessage?.body : getThreadData?.latest?.body; - const { labels: threadLabels } = useThreadLabels( - latestMessage ? latestMessage.tags?.map((t) => t.id!) : [], - ); + const { labels: threadLabels } = useThreadLabels(labels ? labels.map((l) => l.id) : []); const mainSearchTerm = useMemo(() => { if (!searchValue.highlight) return ''; @@ -308,7 +311,7 @@ const Thread = memo( ) : null}

- + {/* */} {Math.random() > 0.5 && (() => { const count = Math.floor(Math.random() * 10) + 1; @@ -419,7 +422,7 @@ const Thread = memo( 'text-md flex items-baseline gap-1 group-hover:opacity-100', )} > - + {highlightText( cleanNameDisplay(latestMessage.sender.name) || '', searchValue.highlight, @@ -436,7 +439,7 @@ const Thread = memo( [{getThreadData.totalReplies}] - + {t('common.mail.replies', { count: getThreadData.totalReplies })} @@ -461,7 +464,7 @@ const Thread = memo( > {highlightText(latestMessage.subject, searchValue.highlight)}

- + {labels ? : null}
{emailContent && (
@@ -771,7 +774,7 @@ export const MailList = memo(({ isCompact }: MailListProps) => { MailList.displayName = 'MailList'; export const MailLabels = memo( - ({ labels }: { labels: Label[] }) => { + ({ labels }: { labels: { id: string; name: string }[] }) => { const t = useTranslations(); if (!labels?.length) return null; diff --git a/apps/mail/hooks/use-threads.ts b/apps/mail/hooks/use-threads.ts index 293eaa76b..354602321 100644 --- a/apps/mail/hooks/use-threads.ts +++ b/apps/mail/hooks/use-threads.ts @@ -159,5 +159,13 @@ export const useThread = (threadId: string | null) => { return totalRecipients > 1; }, [data]); - return { data, isLoading, error, isGroupThread, hasUnread: data?.hasUnread, mutate }; + return { + data, + isLoading, + labels: data?.labels, + error, + isGroupThread, + hasUnread: data?.hasUnread, + mutate, + }; }; diff --git a/apps/mail/lib/email-utils.ts b/apps/mail/lib/email-utils.ts index d13b33cc4..e55686e13 100644 --- a/apps/mail/lib/email-utils.ts +++ b/apps/mail/lib/email-utils.ts @@ -105,7 +105,7 @@ export const getListUnsubscribeAction = ({ }; const FALLBACK_SENDER = { - name: 'No Sender Name', + name: '', email: 'no-sender@unknown', };