File size: 2,697 Bytes
3201ca6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import { useRef } from "react";
import { AnimatePresence, motion, useReducedMotion } from "framer-motion";
import { ChatInterface } from "../../chat/chat-interface";
import { ConversationOverviewPanel } from "../conversation-overview-panel";
import { useConversationStore } from "#/stores/conversation-store";
import { useBreakpoint } from "#/hooks/use-breakpoint";
import { useConversationOverviewColumnSpace } from "#/hooks/use-conversation-overview-column-space";
import {
CONVERSATION_OVERVIEW_COLUMN_WIDTH_PX,
CONVERSATION_OVERVIEW_PANEL_TRANSITION,
} from "../conversation-overview-panel.constants";
interface ChatInterfaceWrapperProps {
isRightPanelShown: boolean;
}
const THREAD_CLASSNAME =
"w-full min-w-0 max-w-[800px] h-full flex flex-col min-h-0";
export function ChatInterfaceWrapper({
isRightPanelShown: _isRightPanelShown,
}: ChatInterfaceWrapperProps) {
const isMobile = useBreakpoint();
const reduceMotion = useReducedMotion();
const enableOverviewMotion = !reduceMotion && import.meta.env.MODE !== "test";
const isOverviewPanelShown = useConversationStore(
(state) => state.isOverviewPanelShown,
);
const containerRef = useRef<HTMLDivElement>(null);
const wantsOverviewPanel = !isMobile && isOverviewPanelShown;
const hasOverviewColumnSpace = useConversationOverviewColumnSpace(
containerRef,
wantsOverviewPanel,
);
const showOverviewPanel = wantsOverviewPanel && hasOverviewColumnSpace;
return (
<div
ref={containerRef}
className="flex h-full min-h-0 w-full overflow-hidden"
>
<div className="flex min-h-0 min-w-0 flex-1 justify-center overflow-hidden">
<div className={THREAD_CLASSNAME}>
<ChatInterface />
</div>
</div>
<AnimatePresence>
{showOverviewPanel ? (
<motion.div
key="conversation-overview-column"
data-testid="conversation-overview-column"
initial={enableOverviewMotion ? { width: 0, opacity: 0 } : false}
animate={{
width: CONVERSATION_OVERVIEW_COLUMN_WIDTH_PX,
opacity: 1,
}}
exit={
enableOverviewMotion ? { width: 0, opacity: 0 } : { opacity: 0 }
}
transition={CONVERSATION_OVERVIEW_PANEL_TRANSITION}
className="flex shrink-0 flex-col items-start overflow-hidden pt-4 pl-3 pr-4"
>
<div
className="w-full shrink-0"
style={{ width: CONVERSATION_OVERVIEW_COLUMN_WIDTH_PX }}
>
<ConversationOverviewPanel />
</div>
</motion.div>
) : null}
</AnimatePresence>
</div>
);
}
|