diff --git a/apps/mail/components/mail/keyboard-shortcuts.tsx b/apps/mail/components/mail/keyboard-shortcuts.tsx
deleted file mode 100644
index 3919cc7f6c..0000000000
--- a/apps/mail/components/mail/keyboard-shortcuts.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-'use client';
-
-import { useAISidebar } from '@/components/ui/ai-sidebar';
-import { navigationConfig } from '@/config/navigation';
-import { useHotKey } from '@/hooks/use-hot-key';
-import { useRouter } from 'next/navigation';
-
-export const KeyboardShortcuts = () => {
- const router = useRouter();
- const { toggleOpen } = useAISidebar();
- if (navigationConfig?.mail?.sections) {
- const items = navigationConfig.mail.sections[0]?.items || [];
- items.map((item, index) => {
- if (item?.url && !item.disabled) {
- useHotKey(`g+${index + 1}`, () => {
- router.push(item.url);
- });
- }
- });
- }
-
- return null;
-};
diff --git a/apps/mail/components/mail/mail-list.tsx b/apps/mail/components/mail/mail-list.tsx
index 3c5ce060d5..6f60f91bff 100644
--- a/apps/mail/components/mail/mail-list.tsx
+++ b/apps/mail/components/mail/mail-list.tsx
@@ -11,23 +11,30 @@ import {
User,
Users,
} from 'lucide-react';
-import type { ConditionalThreadProps, InitialThread, MailListProps, MailSelectMode, ParsedMessage } from '@/types';
+import type {
+ ConditionalThreadProps,
+ InitialThread,
+ MailListProps,
+ MailSelectMode,
+ ParsedMessage,
+} from '@/types';
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 { preloadThread, useThread, useThreads } from '@/hooks/use-threads';
import { ThreadContextMenu } from '@/components/context/thread-context';
-import { useParams, useRouter } from 'next/navigation';
import { cn, FOLDERS, formatDate, getEmailLogo } from '@/lib/utils';
import { Avatar, AvatarImage, AvatarFallback } from '../ui/avatar';
import { useMailNavigation } from '@/hooks/use-mail-navigation';
-import { preloadThread, useThread, useThreads } from '@/hooks/use-threads';
-import { useHotKey, useKeyState } from '@/hooks/use-hot-key';
import { useSearchValue } from '@/hooks/use-search-value';
import { markAsRead, markAsUnread } from '@/actions/mail';
import { ScrollArea } from '@/components/ui/scroll-area';
import { highlightText } from '@/lib/email-utils.client';
+import { useHotkeysContext } from 'react-hotkeys-hook';
+import { useParams, useRouter } from 'next/navigation';
import { useMail } from '@/components/mail/use-mail';
import type { VirtuosoHandle } from 'react-virtuoso';
+import { useKeyState } from '@/hooks/use-hot-key';
import { useSession } from '@/lib/auth-client';
import { Badge } from '@/components/ui/badge';
import { useTranslations } from 'next-intl';
@@ -36,7 +43,7 @@ import { useQueryState } from 'nuqs';
import { Categories } from './mail';
import items from './demo.json';
import { toast } from 'sonner';
-const HOVER_DELAY = 1000;
+const HOVER_DELAY = 1000; // ms before prefetching
const ThreadWrapper = ({
children,
@@ -91,7 +98,7 @@ const Thread = memo(
const hoverTimeoutRef = useRef
| undefined>(undefined);
const isHovering = useRef(false);
const hasPrefetched = useRef(false);
- const {data: getThreadData, isLoading} = useThread(demo ? null : message.id);
+ const { data: getThreadData, isLoading } = useThread(demo ? null : message.id);
const latestMessage = demo ? demoMessage : getThreadData?.latest;
@@ -104,8 +111,8 @@ const Thread = memo(
const isMailBulkSelected = mail.bulkSelected.includes(latestMessage?.threadId ?? message.id);
const threadLabels = useMemo(() => {
- if (!latestMessage) return [];
- return [...(latestMessage.tags || [])];
+ if (!latestMessage) return [];
+ return [...(latestMessage.tags || [])];
}, [latestMessage]);
const isFolderInbox = folder === FOLDERS.INBOX || !folder;
@@ -144,6 +151,7 @@ const Thread = memo(
if (hoverTimeoutRef.current) {
clearTimeout(hoverTimeoutRef.current);
}
+ window.dispatchEvent(new CustomEvent('emailHover', { detail: { id: null } }));
};
// Reset prefetch flag when message changes
@@ -160,10 +168,12 @@ const Thread = memo(
};
}, []);
- if (!demo && (isLoading || !latestMessage || !getThreadData)) return null
+ if (!demo && (isLoading || !latestMessage || !getThreadData)) return null;
- const demoContent = demo && latestMessage ?
-
+
-
+
{highlightText(latestMessage.sender.name, searchValue.highlight)}
{' '}
{latestMessage.unread && !isMailSelected ? (
@@ -234,23 +244,21 @@ const Thread = memo(
) : null}
-
+
{highlightText(latestMessage.subject, searchValue.highlight)}
-