Corp/frontend/src/components/messages/MessagesWorkspaceShell.tsx
2026-08-05 16:43:43 +03:00

81 lines
2.9 KiB
TypeScript

"use client";
import type { ReactNode } from "react";
import { useCallback, useMemo, useState, useSyncExternalStore } from "react";
import { usePathname } from "next/navigation";
import { AppShell } from "@/components/AppShell";
import CreateChatModal from "@/components/messages/CreateChatModal";
import MessagesFocusSidebar from "@/components/messages/MessagesFocusSidebar";
import { MessagesWorkspaceContext } from "@/components/messages/MessagesWorkspaceContext";
import { useUser } from "@/contexts/UserContext";
import { useMessagesWorkspaceMode } from "@/hooks/useMessagesWorkspaceMode";
import {
getMessagesActiveChatId,
isMessagesDialogPath,
resolveEffectiveMessagesWorkspaceMode,
} from "@/lib/messages/workspace.js";
import { isMessengerLaunch } from "@/lib/notifications/installations";
type MessagesWorkspaceShellProps = {
children: ReactNode;
};
function subscribeToMessengerLaunch() {
return () => undefined;
}
export default function MessagesWorkspaceShell({ children }: MessagesWorkspaceShellProps) {
const pathname = usePathname();
const { user } = useUser();
const [createChatOpen, setCreateChatOpen] = useState(false);
const [storedMode, setStoredMode] = useMessagesWorkspaceMode(user?.id);
const messengerLaunch = useSyncExternalStore(
subscribeToMessengerLaunch,
isMessengerLaunch,
() => false,
);
const mode = resolveEffectiveMessagesWorkspaceMode(storedMode, messengerLaunch);
const setMode = useCallback((nextMode: typeof mode) => {
if (!messengerLaunch) setStoredMode(nextMode);
}, [messengerLaunch, setStoredMode]);
const workspaceMode = mode !== "standard";
const immersiveMode = mode === "immersive";
const activeChatId = getMessagesActiveChatId(pathname);
const mobileFullscreen = isMessagesDialogPath(pathname);
const contextValue = useMemo(() => ({
mode,
setMode,
workspaceMode,
immersiveMode,
openCreateChat: () => setCreateChatOpen(true),
}), [immersiveMode, mode, setMode, workspaceMode]);
return (
<MessagesWorkspaceContext.Provider value={contextValue}>
<AppShell
desktopWideMode={workspaceMode}
desktopImmersiveMode={immersiveMode}
standaloneAppMode={messengerLaunch}
mobileFullscreen={mobileFullscreen}
onDesktopWideModeChange={(enabled) => setMode(enabled ? "wide" : "standard")}
suppressPushOnboardingPrompt={workspaceMode}
>
<div className={`h-full min-h-0 ${workspaceMode ? "lg:flex lg:gap-3" : ""}`}>
{workspaceMode ? (
<MessagesFocusSidebar
activeChatId={activeChatId}
mode={mode}
onModeChange={setMode}
onCreateChat={() => setCreateChatOpen(true)}
/>
) : null}
<div className="h-full min-h-0 min-w-0 flex-1">{children}</div>
</div>
<CreateChatModal isOpen={createChatOpen} onClose={() => setCreateChatOpen(false)} />
</AppShell>
</MessagesWorkspaceContext.Provider>
);
}