Skip to content

Commit

Permalink
Merge pull request #11 from GooeyAI/sources_drawer
Browse files Browse the repository at this point in the history
Sources drawer
  • Loading branch information
anish-work authored Nov 19, 2024
2 parents 77460a2 + 39007ab commit 44a5168
Show file tree
Hide file tree
Showing 15 changed files with 508 additions and 172 deletions.
20 changes: 20 additions & 0 deletions src/assets/SvgIcons/IconExternalLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import SvgIcon from "src/components/shared/SvgIcon";

const IconExternalLink = (props: any) => {
const size = props?.size || 16;
return (
<SvgIcon>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
width={size}
height={size}
>
{/* <!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--> */}
<path d="M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l82.7 0L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3l0 82.7c0 17.7 14.3 32 32 32s32-14.3 32-32l0-160c0-17.7-14.3-32-32-32L320 0zM80 32C35.8 32 0 67.8 0 112L0 432c0 44.2 35.8 80 80 80l320 0c44.2 0 80-35.8 80-80l0-112c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 112c0 8.8-7.2 16-16 16L80 448c-8.8 0-16-7.2-16-16l0-320c0-8.8 7.2-16 16-16l112 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L80 32z" />
</svg>
</SvgIcon>
);
};

export default IconExternalLink;
5 changes: 3 additions & 2 deletions src/components/shared/Buttons/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ const Button = ({
<div
className={clsx(
"pos-relative w-100 h-100",
hideOverflow && "btn-hide-overflow"
hideOverflow && "btn-hide-overflow",
)}
>
{rest.children}
{RightIconComponent && (
<div
className={clsx(
"btn-icon right-icon",
showIconOnHover && "icon-hover"
"flex items-center justify-center",
showIconOnHover && "icon-hover",
)}
>
<RightIconComponent />
Expand Down
8 changes: 5 additions & 3 deletions src/components/shared/Layout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Header from "src/widgets/copilot/components/Header";
import { addInlineStyle } from "src/addStyles";
import style from "./appLayout.scss?inline";
import SideNavbar from "./SideNavbar";
import SecondaryDrawer from "./SecondaryDrawer";

addInlineStyle(style);

Expand All @@ -21,7 +22,7 @@ const CHAT_WINDOW_WIDTH = 760;
const generateParentContainerClass = (
isInline: boolean,
isFullScreen: boolean,
isFocusMode: boolean
isFocusMode: boolean,
) => {
if (!isInline) {
if (isFocusMode) return "gooey-focused-popup";
Expand Down Expand Up @@ -67,8 +68,8 @@ const AppLayout = ({ children }: Props) => {
generateParentContainerClass(
layoutController!.isInline,
config?.mode === "fullscreen",
layoutController!.isFocusMode
)
layoutController!.isFocusMode,
),
)}
>
<div className="d-flex h-100 pos-relative">
Expand All @@ -85,6 +86,7 @@ const AppLayout = ({ children }: Props) => {
<>{children}</>
</div>
</main>
<SecondaryDrawer />
</div>
</div>
);
Expand Down
144 changes: 144 additions & 0 deletions src/components/shared/Layout/SecondaryDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { useSystemContext } from "src/contexts/hooks";
import clsx from "clsx";
import { useEffect, useRef, useState } from "react";

const MIN_DRAWER_WIDTH = 300;
const MAX_DRAWER_WIDTH = 800;
const RESIZE_HANDLE_WIDTH = 5;

const SecondaryDrawer = () => {
const { layoutController } = useSystemContext();
const drawerRef = useRef<HTMLDivElement>(null);
const [isResizing, setIsResizing] = useState(false);
const [drawerWidth, setDrawerWidth] = useState(window.innerWidth * 0.65);

useEffect(() => {
const sideBarElement = drawerRef.current;

if (!sideBarElement || !layoutController?.isSecondaryDrawerOpen) return;

if (layoutController?.isMobile) {
sideBarElement.style.width = "100%";
sideBarElement.style.position = "absolute !important";
} else {
if (layoutController?.isSecondaryDrawerOpen) {
sideBarElement.style.width = `${drawerWidth}px`;
sideBarElement.style.position = "relative !important";
}
}
}, [
layoutController?.isMobile,
layoutController?.isSecondaryDrawerOpen,
drawerWidth,
]);

const handleMouseDown = (e: React.MouseEvent) => {
if (layoutController?.isMobile) return;
setIsResizing(true);
e.preventDefault();
};

useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (!isResizing) return;

const container = drawerRef.current?.parentElement;
if (!container) return;

const containerRect = container.getBoundingClientRect();
const newWidth = containerRect.right - e.clientX;

const constrainedWidth = Math.min(
Math.max(newWidth, MIN_DRAWER_WIDTH),
Math.max(MAX_DRAWER_WIDTH, containerRect.width * 0.8),
);

setDrawerWidth(constrainedWidth);
};

const handleMouseUp = () => {
setIsResizing(false);
};

if (isResizing) {
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp);
document.body.style.userSelect = "none";
document.body.style.cursor = "ew-resize";
} else {
document.body.style.userSelect = "";
document.body.style.cursor = "";
}

return () => {
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
document.body.style.userSelect = "";
document.body.style.cursor = "";
};
}, [isResizing]);

return (
<div
ref={drawerRef}
id="gooey-right-bar"
style={{
zIndex: 10,
transition: isResizing ? "none" : "width 0.2s ease",
position: layoutController?.isMobile ? "absolute" : "relative",
}}
className={clsx(
"h-100 top-0 overflow-x-hidden right-0 bg-grey d-flex flex-col",
)}
>
{/* Content Container */}
<div className="h-100 w-100 flex-1 d-flex flex-col">
{layoutController?.secondaryDrawerContent?.()}
</div>

{/* Resize System */}
{!layoutController?.isMobile && (
<div
style={{
position: "absolute",
top: 0,
left: -RESIZE_HANDLE_WIDTH / 2,
width: `${RESIZE_HANDLE_WIDTH}px`,
height: "100%",
cursor: "ew-resize",
zIndex: 20,
}}
className={clsx(isResizing && "bg-light")}
onMouseDown={handleMouseDown}
>
<div
style={{
position: "absolute",
left: RESIZE_HANDLE_WIDTH / 2,
width: "5px",
height: "100%",
}}
className="bg-white b-lt-1 b-rt-1 drawer-resize-bar"
/>
</div>
)}

{/* Full-screen overlay during resize */}
{isResizing && (
<div
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 19,
cursor: "ew-resize",
}}
/>
)}
</div>
);
};

export default SecondaryDrawer;
25 changes: 16 additions & 9 deletions src/components/shared/Layout/SideNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ const SideNavbar = () => {
}}
className={clsx(
"b-rt-1 h-100 overflow-x-hidden top-0 left-0 bg-grey d-flex flex-col",
layoutController?.isMobile ? "pos-absolute" : "pos-relative"
layoutController?.isMobile ? "pos-absolute" : "pos-relative",
)}
>
<div
Expand Down Expand Up @@ -176,13 +176,15 @@ const SideNavbar = () => {
<div className="gp-8">
<GooeyTooltip text="New Chat" direction="right" disabled={isEmpty}>
<Button
className="w-100 pos-relative text-muted"
className="w-100 pos-relative text-dark"
disabled={isEmpty}
onClick={handleNewConversation}
onClick={() => {
handleNewConversation();
if (layoutController?.isSecondaryDrawerOpen)
layoutController?.toggleSecondaryDrawer(null);
}}
hideOverflow
RightIconComponent={() => (
<IconPencilEdit size={18} className="text-muted" />
)}
RightIconComponent={() => <IconPencilEdit size={18} />}
>
<div className="d-flex align-center">
<div
Expand All @@ -205,15 +207,18 @@ const SideNavbar = () => {
/>
</div>
<p
className="font_16_600 text-left text-almostBlack"
className={clsx(
"font_16_600 text-left",
isEmpty ? "text-muted" : "text-almostBlack",
)}
style={{
maxWidth: "70%",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}
>
{branding?.name}
New Chat
</p>
</div>
</Button>
Expand Down Expand Up @@ -242,7 +247,7 @@ const SideNavbar = () => {
.sort(
(a: Conversation, b: Conversation) =>
new Date(b.timestamp as string).getTime() -
new Date(a.timestamp as string).getTime()
new Date(a.timestamp as string).getTime(),
)
.map((conversation: Conversation) => {
return (
Expand All @@ -256,6 +261,8 @@ const SideNavbar = () => {
setActiveConversation(conversation);
if (layoutController?.isMobile)
layoutController?.toggleSidebar();
if (layoutController?.isSecondaryDrawerOpen)
layoutController?.toggleSecondaryDrawer(null);
}}
/>
</li>
Expand Down
20 changes: 19 additions & 1 deletion src/components/shared/Link.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
import { useSystemContext } from "src/contexts/hooks";
import { FullSourcePreview } from "src/widgets/copilot/components/Messages/Sources";

const Link = (props: any) => {
const { layoutController } = useSystemContext();

const handleClick = () => {
layoutController?.toggleSecondaryDrawer?.(() => (
<FullSourcePreview
data={props?.data}
layoutController={layoutController}
/>
));
};

return (
<a href={props?.to} target="_blank" style={{ color: props.configColor }}>
<a
onClick={() => handleClick()}
style={{ color: props.configColor }}
className="gooey-link cr-pointer"
>
{props.children}
</a>
);
Expand Down
Loading

0 comments on commit 44a5168

Please sign in to comment.