"use client" import { Suspense, useCallback, useEffect, useLayoutEffect, useState, } from "react" import { useIsXs } from "@/hooks/use-xs" import { readTouchNavMatches, useTouchNav } from "@/hooks/use-touch-nav" import { useMailSplitView } from "@/hooks/use-mail-split-view" import { useMailRoute } from "@/hooks/use-mail-route" import { parseSearchParams } from "@/lib/mail-search/search-params" import { searchParamsToDisplayQuery } from "@/lib/mail-search/search-filter" import { MobileBottomBar } from "@/components/gmail/mobile-bottom-bar" import { MobileSearchOverlay } from "@/components/gmail/mobile-search-overlay" import type { MailXsViewChrome } from "@/lib/mail-xs-view-chrome" import { useRouter, usePathname } from "next/navigation" import { Sidebar } from "@/components/gmail/sidebar" import { Header } from "@/components/gmail/header" import { EmailList } from "@/components/gmail/email-list" import { RightPanel } from "@/components/gmail/right-panel" import { ContactsPanel } from "@/components/gmail/contacts/contacts-panel" import { EmailDragProvider } from "@/lib/drag-context" import { MoveDragIndicator } from "@/components/gmail/move-drag-indicator" import { ComposeProvider } from "@/lib/compose-context" import { ScheduledMailProvider } from "@/lib/scheduled-mail-context" import { ComposeModalManager } from "@/components/gmail/compose-modal" import { PendingComposeBridge } from "@/components/gmail/pending-compose-bridge" import { SidebarNavProvider } from "@/lib/sidebar-nav-context" import { mailNavVisitKey } from "@/lib/mail-folder-display" import { MailDocumentTitle } from "@/components/gmail/mail-document-title" import { useMailStore } from "@/lib/stores/mail-store" import { useMailUiStore } from "@/lib/stores/mail-ui-store" import { DEFAULT_INBOX_TAB } from "@/lib/mail-url" import { cn } from "@/lib/utils" import { ThemeProvider } from "@/components/theme-provider" import { MailThemeApplier } from "@/components/gmail/mail-theme-applier" import { QuickSettingsRoot } from "@/components/gmail/quick-settings/quick-settings-root" import { MailSettingsSync } from "@/components/gmail/mail-settings-sync" import { MailNavSync } from "@/components/gmail/mail-nav-sync" import { ComposeIdentitiesSync } from "@/components/gmail/compose-identities-sync" import { MailSignaturesSync } from "@/components/gmail/mail-signatures-sync" import { MailNotificationsBridge } from "@/components/gmail/mail-notifications-bridge" import { useWebSocket } from "@/lib/api/ws" import { useMailSettingsStore } from "@/lib/stores/mail-settings-store" import { FilePreviewDialog } from "@/components/drive/file-preview-dialog" import { AiChatPanel } from "@/components/ai/ai-chat-panel" const MAIL_SETTINGS_PATH = "/mail/settings" function isMailSettingsPath(pathname: string | null): boolean { return pathname === MAIL_SETTINGS_PATH || pathname?.startsWith(`${MAIL_SETTINGS_PATH}/`) === true } function MailAppInner() { const router = useRouter() const { route, navigateRoute, searchParams: currentSearchParams } = useMailRoute() const activeSearchQuery = route.folderId === "search" ? searchParamsToDisplayQuery(parseSearchParams(currentSearchParams)) : "" const isXs = useIsXs() const touchNav = useTouchNav() const splitView = useMailSplitView() const pushRecentFolderVisit = useMailStore((s) => s.pushRecentFolderVisit) const sidebarCollapsed = useMailUiStore((s) => s.sidebarCollapsed) const setSidebarCollapsed = useMailUiStore((s) => s.setSidebarCollapsed) const mobileSearchOpen = useMailUiStore((s) => s.mobileSearchOpen) const setMobileSearchOpen = useMailUiStore((s) => s.setMobileSearchOpen) const folderUnreadCounts = useMailUiStore((s) => s.folderUnreadCounts) const setFolderUnreadCounts = useMailUiStore((s) => s.setFolderUnreadCounts) const [xsViewChrome, setXsViewChrome] = useState(null) useLayoutEffect(() => { if (!readTouchNavMatches()) setSidebarCollapsed(false) }, [setSidebarCollapsed]) useEffect(() => { if (isXs) setSidebarCollapsed(true) }, [isXs, setSidebarCollapsed]) useEffect(() => { if (route.folderId !== "search") { pushRecentFolderVisit(mailNavVisitKey(route.folderId, route.inboxTab)) } }, [route.folderId, route.inboxTab, pushRecentFolderVisit]) const handleSelectFolder = useCallback( (id: string) => { useMailUiStore.getState().requestSuppressSplitAutoOpen() navigateRoute({ folderId: id, inboxTab: DEFAULT_INBOX_TAB, page: 1, mailId: null, }) if (readTouchNavMatches()) setSidebarCollapsed(true) }, [navigateRoute, setSidebarCollapsed] ) return ( { useMailUiStore.getState().requestSuppressSplitAutoOpen() navigateRoute({ folderId: nextFolderId, inboxTab: DEFAULT_INBOX_TAB, page: 1, mailId: null, }) }} >
{!splitView ? (
setSidebarCollapsed(!sidebarCollapsed)} onOpenMobileSearch={() => setMobileSearchOpen(true)} />
) : null}
{!sidebarCollapsed && touchNav && (
) } export function MailAppShell({ children: routeOutlet, }: { children: React.ReactNode }) { const pathname = usePathname() const showSettingsPage = isMailSettingsPath(pathname) useWebSocket() useEffect(() => { if (showSettingsPage) { useMailSettingsStore.getState().setQuickSettingsOpen(false) } }, [showSettingsPage]) useEffect(() => { const blockPinch = (event: Event) => event.preventDefault() document.addEventListener("gesturestart", blockPinch, { passive: false }) document.addEventListener("gesturechange", blockPinch, { passive: false }) document.addEventListener("gestureend", blockPinch, { passive: false }) return () => { document.removeEventListener("gesturestart", blockPinch) document.removeEventListener("gesturechange", blockPinch) document.removeEventListener("gestureend", blockPinch) } }, []) return (
} > {showSettingsPage ? ( {routeOutlet} ) : ( )} ) }