Files
ihasmail/web/src/views/compose/ComposerDock.tsx
T
jcoffey-dev 6139031689 Load the composer, previews, dialogs and other sidebars on demand
The main chunk carried everything the mail view might open: the file
preview and its Markdown renderer, the composer and its editor, the contact
editor, the filter and share dialogs, and the calendar, contacts and files
sidebars. Each is now loaded when first shown. The composer is also
fetched when the browser is idle after startup, so the first Compose does
not wait on the network.

Import the notification helpers statically where they already were: the
dynamic imports beside those static ones split nothing.
2026-09-16 09:48:04 -07:00

37 lines
1.5 KiB
TypeScript

import { lazy, Suspense } from "react";
import { useCompose } from "@/store/compose";
import { useIsMobile } from "@/ui/misc";
/*
* The composer -- the rich-text editor, the recipient and file pickers -- is
* loaded apart from the mail view, and fetched while the browser is idle
* after startup so the first Compose does not wait on the network.
*/
const loadComposer = () => import("./Composer");
const Composer = lazy(() => loadComposer().then((m) => ({ default: m.Composer })));
if (typeof window !== "undefined") {
const warm = () => void loadComposer().catch(() => {});
if ("requestIdleCallback" in window) window.requestIdleCallback(warm, { timeout: 5000 });
else setTimeout(warm, 2000);
}
export function ComposerDock() {
const drafts = useCompose((s) => s.drafts);
const activeKey = useCompose((s) => s.activeKey);
const isMobile = useIsMobile();
if (!drafts.length) return null;
// On mobile only the active composer is shown (full screen); others are minimized bars.
const visible = isMobile ? drafts.filter((d) => d.key === activeKey || d.minimized) : drafts;
// On desktop a full-screen composer stands alone: the rest are hidden until it is restored.
const hasMaximized = !isMobile && drafts.some((d) => d.maximized && !d.minimized);
return (
<div className={`composer-dock${hasMaximized ? " has-maximized" : ""}`}>
<Suspense fallback={null}>
{visible.map((d) => (
<Composer key={d.key} draft={isMobile && d.key !== activeKey ? { ...d, minimized: true } : d} />
))}
</Suspense>
</div>
);
}