81 lines
2.9 KiB
TypeScript
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>
|
|
);
|
|
}
|