From 36795f06283f9e6005f9dc6537b9def7a64fe9b8 Mon Sep 17 00:00:00 2001 From: Nizzy Date: Thu, 20 Mar 2025 13:29:18 -0400 Subject: [PATCH 1/7] threadid in url when user opens email --- apps/mail/components/mail/mail-list.tsx | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/apps/mail/components/mail/mail-list.tsx b/apps/mail/components/mail/mail-list.tsx index 675120095c..562724bc05 100644 --- a/apps/mail/components/mail/mail-list.tsx +++ b/apps/mail/components/mail/mail-list.tsx @@ -15,7 +15,7 @@ import { useMail } from '@/components/mail/use-mail'; import type { VirtuosoHandle } from 'react-virtuoso'; import { useSession } from '@/lib/auth-client'; import { Badge } from '@/components/ui/badge'; -import { useParams } from 'next/navigation'; +import { useParams, useRouter, useSearchParams } from 'next/navigation'; import { useTranslations } from 'next-intl'; import { Virtuoso } from 'react-virtuoso'; import items from './demo.json'; @@ -204,6 +204,8 @@ export const MailList = memo(({ isCompact }: MailListProps) => { const [mail, setMail] = useMail(); const { data: session } = useSession(); const t = useTranslations(); + const router = useRouter(); + const searchParams = useSearchParams(); const sessionData = useMemo( () => ({ @@ -380,25 +382,40 @@ export const MailList = memo(({ isCompact }: MailListProps) => { return; } - if (mail.selected === message.threadId || mail.selected === message.id) { + const threadId = message.threadId ?? message.id; + + if (mail.selected === threadId) { + // Deselect the thread and update URL to remove threadId setMail({ selected: null, bulkSelected: [], }); + + // Update URL to remove threadId + const currentParams = new URLSearchParams(searchParams.toString()); + currentParams.delete('threadId'); + router.push(`/mail/${folder}?${currentParams.toString()}`); } else { + // Select the thread and update URL with threadId setMail({ ...mail, - selected: message.threadId ?? message.id, + selected: threadId, bulkSelected: [], }); + + // Update URL with threadId + const currentParams = new URLSearchParams(searchParams.toString()); + currentParams.set('threadId', threadId); + router.push(`/mail/${folder}?${currentParams.toString()}`); } + if (message.unread) { return markAsRead({ ids: [message.id] }) .then(() => mutate()) .catch(console.error); } }, - [mail, setMail, items, getSelectMode], + [mail, setMail, items, getSelectMode, router, searchParams, folder], ); const isEmpty = items.length === 0; From a33243a6375a2993ef91e7a89b277aef0a4b7268 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 17:30:10 +0000 Subject: [PATCH 2/7] Apply Prettier format --- apps/mail/components/mail/mail-list.tsx | 10 +++++----- apps/mail/components/mail/thread-subject.tsx | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/mail/components/mail/mail-list.tsx b/apps/mail/components/mail/mail-list.tsx index 562724bc05..9bb3987ec4 100644 --- a/apps/mail/components/mail/mail-list.tsx +++ b/apps/mail/components/mail/mail-list.tsx @@ -5,6 +5,7 @@ import { AlertTriangle, Bell, Briefcase, StickyNote, Tag, User, Users } from 'lu import { type ComponentProps, memo, useCallback, useEffect, useMemo, useRef } from 'react'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; import { EmptyState, type FolderType } from '@/components/mail/empty-state'; +import { useParams, useRouter, useSearchParams } from 'next/navigation'; import { preloadThread, useThreads } from '@/hooks/use-threads'; import { cn, defaultPageSize, formatDate } from '@/lib/utils'; import { useHotKey, useKeyState } from '@/hooks/use-hot-key'; @@ -15,7 +16,6 @@ import { useMail } from '@/components/mail/use-mail'; import type { VirtuosoHandle } from 'react-virtuoso'; import { useSession } from '@/lib/auth-client'; import { Badge } from '@/components/ui/badge'; -import { useParams, useRouter, useSearchParams } from 'next/navigation'; import { useTranslations } from 'next-intl'; import { Virtuoso } from 'react-virtuoso'; import items from './demo.json'; @@ -383,14 +383,14 @@ export const MailList = memo(({ isCompact }: MailListProps) => { } const threadId = message.threadId ?? message.id; - + if (mail.selected === threadId) { // Deselect the thread and update URL to remove threadId setMail({ selected: null, bulkSelected: [], }); - + // Update URL to remove threadId const currentParams = new URLSearchParams(searchParams.toString()); currentParams.delete('threadId'); @@ -402,13 +402,13 @@ export const MailList = memo(({ isCompact }: MailListProps) => { selected: threadId, bulkSelected: [], }); - + // Update URL with threadId const currentParams = new URLSearchParams(searchParams.toString()); currentParams.set('threadId', threadId); router.push(`/mail/${folder}?${currentParams.toString()}`); } - + if (message.unread) { return markAsRead({ ids: [message.id] }) .then(() => mutate()) diff --git a/apps/mail/components/mail/thread-subject.tsx b/apps/mail/components/mail/thread-subject.tsx index 965607c88f..52fcaf3383 100644 --- a/apps/mail/components/mail/thread-subject.tsx +++ b/apps/mail/components/mail/thread-subject.tsx @@ -44,7 +44,7 @@ export default function ThreadSubject({ subject, isMobile }: ThreadSubjectProps) From 46dc12e581830d0bf46b33a3e612ec7af5a4bed7 Mon Sep 17 00:00:00 2001 From: Nizzy Date: Thu, 20 Mar 2025 13:52:04 -0400 Subject: [PATCH 3/7] fixes --- apps/mail/components/mail/mail-list.tsx | 40 ++++++++++---------- apps/mail/components/mail/mail.tsx | 26 ++++++++----- apps/mail/components/mail/thread-display.tsx | 12 ++++-- apps/mail/hooks/use-threads.ts | 4 +- 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/apps/mail/components/mail/mail-list.tsx b/apps/mail/components/mail/mail-list.tsx index 9bb3987ec4..204cee3603 100644 --- a/apps/mail/components/mail/mail-list.tsx +++ b/apps/mail/components/mail/mail-list.tsx @@ -48,13 +48,16 @@ const Thread = memo( const [mail] = useMail(); const [searchValue] = useSearchValue(); const t = useTranslations(); + const searchParams = useSearchParams(); + const threadIdParam = searchParams.get('threadId'); const hoverTimeoutRef = useRef | undefined>(undefined); const isHovering = useRef(false); const hasPrefetched = useRef(false); const isMailSelected = useMemo(() => { - return message.id === mail.selected; - }, [message.id, mail.selected]); + const threadId = message.threadId ?? message.id; + return threadId === threadIdParam; + }, [message.id, message.threadId, threadIdParam]); const isMailBulkSelected = mail.bulkSelected.includes(message.id); @@ -136,7 +139,7 @@ const Thread = memo( 'text-md flex items-baseline gap-1 group-hover:opacity-100', )} > - + {highlightText(message.sender.name, searchValue.highlight)} {' '} {message.unread ? : null} @@ -206,6 +209,7 @@ export const MailList = memo(({ isCompact }: MailListProps) => { const t = useTranslations(); const router = useRouter(); const searchParams = useSearchParams(); + const threadIdParam = searchParams.get('threadId'); const sessionData = useMemo( () => ({ @@ -353,7 +357,7 @@ export const MailList = memo(({ isCompact }: MailListProps) => { if (selectMode === 'range') { const lastSelectedItem = - mail.bulkSelected[mail.bulkSelected.length - 1] ?? mail.selected ?? message.id; + mail.bulkSelected[mail.bulkSelected.length - 1] ?? threadIdParam ?? message.id; const mailsIndex = items.map((m) => m.id); const startIdx = mailsIndex.indexOf(lastSelectedItem); @@ -383,29 +387,27 @@ export const MailList = memo(({ isCompact }: MailListProps) => { } const threadId = message.threadId ?? message.id; - - if (mail.selected === threadId) { + const currentParams = new URLSearchParams(searchParams.toString()); + + if (threadIdParam === threadId) { // Deselect the thread and update URL to remove threadId - setMail({ - selected: null, + currentParams.delete('threadId'); + setMail(prev => ({ + ...prev, bulkSelected: [], - }); - + })); + // Update URL to remove threadId - const currentParams = new URLSearchParams(searchParams.toString()); - currentParams.delete('threadId'); router.push(`/mail/${folder}?${currentParams.toString()}`); } else { // Select the thread and update URL with threadId - setMail({ - ...mail, - selected: threadId, + currentParams.set('threadId', threadId); + setMail(prev => ({ + ...prev, bulkSelected: [], - }); - + })); + // Update URL with threadId - const currentParams = new URLSearchParams(searchParams.toString()); - currentParams.set('threadId', threadId); router.push(`/mail/${folder}?${currentParams.toString()}`); } diff --git a/apps/mail/components/mail/mail.tsx b/apps/mail/components/mail/mail.tsx index aaab5780ed..84ba9a034c 100644 --- a/apps/mail/components/mail/mail.tsx +++ b/apps/mail/components/mail/mail.tsx @@ -148,7 +148,7 @@ export function DemoMailLayout() {
- +
@@ -197,18 +197,24 @@ export function MailLayout() { return () => window.removeEventListener('resize', checkIsMobile); }, []); + const searchParams = useSearchParams(); + const threadIdParam = searchParams.get('threadId'); + useEffect(() => { - if (mail.selected) { + if (threadIdParam) { setOpen(true); } else { setOpen(false); } - }, [mail.selected]); + }, [threadIdParam]); const handleClose = useCallback(() => { setOpen(false); - setMail((mail) => ({ ...mail, selected: null })); - }, [setMail]); + // Update URL to remove threadId parameter + const currentParams = new URLSearchParams(searchParams.toString()); + currentParams.delete('threadId'); + router.push(`/mail/${folder}?${currentParams.toString()}`); + }, [router, folder, searchParams]); useHotKey('/', () => { setSearchMode(true); @@ -234,7 +240,7 @@ export function MailLayout() {
- +