Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions apps/desktop/src/components/toolbar/bars/main-toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ import { useMatch } from "@tanstack/react-router";
import { DeleteNoteButton } from "@/components/toolbar/buttons/delete-note-button";
import { NewNoteButton } from "@/components/toolbar/buttons/new-note-button";
import { NewWindowButton } from "@/components/toolbar/buttons/new-window-button";
// import { ShareButton } from "@/components/toolbar/buttons/share-button";
import { getCurrentWebviewWindowLabel } from "@hypr/plugin-windows";
import { ChatPanelButton } from "@hypr/ui/components/block/chat-panel-button";
import { cn } from "@hypr/ui/lib/utils";
import { useLeftSidebar } from "@hypr/utils/contexts";
import { useLeftSidebar, useRightPanel } from "@hypr/utils/contexts";
import { SearchBar } from "../../search-bar";
import { ChatPanelButton } from "../buttons/chat-panel-button";
import { LeftSidebarButton } from "../buttons/left-sidebar-button";
import { ShareButton } from "../buttons/share-button";

Expand All @@ -24,6 +23,8 @@ export function MainToolbar() {
const isNote = !!noteMatch;
const isMain = getCurrentWebviewWindowLabel() === "main";

const { isExpanded: isChatPanelExpanded, togglePanel: toggleChatPanel } = useRightPanel();

return (
<header
data-tauri-drag-region
Expand Down Expand Up @@ -58,7 +59,7 @@ export function MainToolbar() {
<>
{(organizationMatch || humanMatch) && <NewWindowButton />}
{isNote && <ShareButton />}
<ChatPanelButton />
<ChatPanelButton isExpanded={isChatPanelExpanded} togglePanel={toggleChatPanel} />
</>
)}
</div>
Expand Down
53 changes: 0 additions & 53 deletions apps/desktop/src/components/toolbar/buttons/chat-panel-button.tsx

This file was deleted.

70 changes: 47 additions & 23 deletions apps/desktop2/src/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,40 +53,64 @@ export function Chat() {

if (!currentChatGroupId || !messageIds?.length) {
return (
<div className="border border-gray-300 rounded p-2">
<div className="text-gray-500">Select or create a chat group</div>

<div className="flex flex-col gap-2">
{chatGroupIds?.map((chatGroupId) => (
<ChatGroup
key={chatGroupId}
id={chatGroupId}
handleClick={() => setCurrentChatGroupId(chatGroupId)}
<div className="h-full flex flex-col bg-gray-100">
<div className="flex-1 overflow-y-auto p-4">
<div className="flex flex-col gap-2">
{chatGroupIds?.map((chatGroupId) => (
<ChatGroup
key={chatGroupId}
id={chatGroupId}
handleClick={() => setCurrentChatGroupId(chatGroupId)}
/>
))}
</div>
</div>

<div className="border-t border-gray-300 p-4">
<form onSubmit={handleSubmitMessage}>
<textarea
name="message"
placeholder="Type a message..."
className="w-full border border-gray-300 rounded p-2 resize-none focus:outline-none focus:ring-2 focus:ring-blue-500"
rows={3}
/>
))}
<button className="mt-2 border border-gray-300 rounded px-4 py-2 hover:bg-gray-100">
Send
</button>
</form>
</div>
</div>
);
}

return (
<div className="border border-gray-300 rounded p-2">
<button onClick={() => setCurrentChatGroupId("")}>
reset
</button>
<div className="h-full flex flex-col border border-gray-300 rounded">
<div className="border-b border-gray-300 p-2">
<button
onClick={() => setCurrentChatGroupId("")}
className="border border-gray-300 rounded px-3 py-1 hover:bg-gray-100"
>
reset
</button>
</div>

<div className="space-y-2">
<div className="flex-1 overflow-y-auto p-4 space-y-2">
{messageIds?.map((messageId) => <ChatMessage key={messageId} messageId={messageId} />)}
</div>

<form onSubmit={handleSubmitMessage}>
<input
name="message"
type="text"
className="border border-gray-300 rounded p-2"
/>
<button className="border border-gray-300 rounded p-2">Send</button>
</form>
<div className="border-t border-gray-300 p-4">
<form onSubmit={handleSubmitMessage} className="flex flex-col gap-2">
<textarea
name="message"
placeholder="Type a message..."
className="w-full border border-gray-300 rounded p-2 resize-none focus:outline-none focus:ring-2 focus:ring-blue-500"
rows={3}
/>
<button className="self-end border border-gray-300 rounded px-4 py-2 hover:bg-gray-100">
Send
</button>
</form>
</div>
</div>
);
}
Expand Down
74 changes: 62 additions & 12 deletions apps/desktop2/src/components/main/left-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import { Link } from "@tanstack/react-router";
import { clsx } from "clsx";
import { ChartNoAxesGantt, FolderOpenIcon } from "lucide-react";
import { ChartNoAxesGantt, FolderOpenIcon, PanelLeftCloseIcon, SearchIcon } from "lucide-react";
import { useState } from "react";
import { useCell, useRowIds, useSliceRowIds } from "tinybase/ui-react";

import * as persisted from "../../tinybase/store/persisted";

import { ContextMenuItem } from "@hypr/ui/components/ui/context-menu";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@hypr/ui/components/ui/tabs";
import { useLeftSidebar } from "@hypr/utils/contexts";
import { useTabs } from "../../hooks/useTabs";
import { Tab } from "../../types";
import { InteractiveButton } from "../interactive-button";

export function LeftSidebar() {
const { togglePanel: toggleLeftPanel } = useLeftSidebar();

return (
<div className="h-screen border-r w-[300px]">
<Tabs defaultValue="timeline">
<div className="h-full border-r w-full flex flex-col overflow-hidden">
<Tabs defaultValue="timeline" className="flex flex-col flex-1 overflow-hidden">
<TabsList
data-tauri-drag-region
className={clsx([
"h-full flex flex-row",
"flex flex-row shrink-0",
"flex w-full items-center justify-between min-h-11 py-1 px-2 border-b",
"border-border bg-neutral-50",
"pl-[72px]",
Expand All @@ -31,14 +34,32 @@ export function LeftSidebar() {
<TabsTrigger value="timeline" className="flex-1">
<ChartNoAxesGantt />
</TabsTrigger>
<TabsTrigger value="search" className="flex-1">
<SearchIcon />
</TabsTrigger>

<PanelLeftCloseIcon
onClick={toggleLeftPanel}
className="cursor-pointer h-5 w-5"
/>
</TabsList>

<TabsContent value="timeline" className="flex-1 overflow-auto p-2 mt-0">
<TimelineView />
<TabsContent value="timeline" className="flex-1 mt-0 h-0">
<div className="h-full overflow-y-auto p-2">
<TimelineView />
</div>
</TabsContent>

<TabsContent value="folder" className="flex-1 mt-0 h-0">
<div className="h-full overflow-y-auto p-2">
<FolderView />
</div>
</TabsContent>

<TabsContent value="folder" className="flex-1 overflow-auto p-2 mt-0">
<FolderView />
<TabsContent value="search" className="flex-1 mt-0 h-0">
<div className="h-full flex flex-col overflow-hidden">
<SearchView />
</div>
</TabsContent>
</Tabs>
</div>
Expand All @@ -47,29 +68,53 @@ export function LeftSidebar() {

function TimelineView() {
const allSessionIds = useRowIds("sessions", persisted.STORE_ID);
const { currentTab } = useTabs();

return (
<div className="flex flex-col">
{allSessionIds?.map((sessionId) => <SessionItem key={sessionId} sessionId={sessionId} />)}
{allSessionIds?.map((sessionId) => (
<SessionItem key={sessionId} sessionId={sessionId} active={currentTab?.id === sessionId} />
))}
</div>
);
}

function SearchView() {
return (
<>
<div className="sticky top-0 bg-white z-10 p-2 border-b">
<input
type="text"
placeholder="Search..."
className="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="flex-1 overflow-y-auto p-2">
{/* Search results will go here */}
</div>
</>
);
}

function FolderView() {
const rootFolderIds = useSliceRowIds(persisted.INDEXES.foldersByParent, "", persisted.STORE_ID);
const rootSessionIds = useSliceRowIds(persisted.INDEXES.sessionsByFolder, "", persisted.STORE_ID);
const { currentTab } = useTabs();

return (
<div className="flex flex-col">
{rootFolderIds?.map((folderId) => <FolderTreeItem key={folderId} folderId={folderId} />)}

{rootSessionIds?.map((sessionId) => <SessionItemNested key={sessionId} sessionId={sessionId} depth={0} />)}
{rootSessionIds?.map((sessionId) => (
<SessionItemNested key={sessionId} sessionId={sessionId} depth={0} active={currentTab?.id === sessionId} />
))}
</div>
);
}

function FolderTreeItem({ folderId, depth = 0 }: { folderId: string; depth?: number }) {
const [isOpen, setIsOpen] = useState(true);
const { currentTab } = useTabs();

const name = useCell("folders", folderId, "name", persisted.STORE_ID);
const sessionIds = useSliceRowIds(persisted.INDEXES.sessionsByFolder, folderId, persisted.STORE_ID);
const subFolderIds = useSliceRowIds(persisted.INDEXES.foldersByParent, folderId, persisted.STORE_ID);
Expand All @@ -92,7 +137,12 @@ function FolderTreeItem({ folderId, depth = 0 }: { folderId: string; depth?: num
{isOpen && (
<>
{sessionIds?.map((sessionId) => (
<SessionItemNested key={sessionId} sessionId={sessionId} depth={depth + 1} />
<SessionItemNested
key={sessionId}
sessionId={sessionId}
depth={depth + 1}
active={currentTab?.id === sessionId}
/>
))}

{subFolderIds?.map((subId) => <FolderTreeItem key={subId} folderId={subId} depth={depth + 1} />)}
Expand Down
Loading
Loading