Skip to content

Commit a38ca42

Browse files
Merge pull request #69 from generalaction/design/collapseSides
Design/collapse sides
2 parents 95f7d23 + b207128 commit a38ca42

File tree

8 files changed

+186
-81
lines changed

8 files changed

+186
-81
lines changed

src/main/ipc/appIpc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ export function registerAppIpc() {
1515
// App metadata
1616
ipcMain.handle('app:getVersion', () => app.getVersion())
1717
ipcMain.handle('app:getPlatform', () => process.platform)
18-
}
1918

19+
}

src/renderer/App.tsx

Lines changed: 90 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,27 @@ import RequirementsNotice from "./components/RequirementsNotice";
1313
import { useToast } from "./hooks/use-toast";
1414
import { useGithubAuth } from "./hooks/useGithubAuth";
1515
import emdashLogo from "../assets/images/emdash/emdash_logo.svg";
16+
import Titlebar from "./components/titlebar/Titlebar";
17+
import { SidebarProvider, useSidebar } from "./components/ui/sidebar";
18+
19+
const SidebarHotkeys: React.FC = () => {
20+
const { toggle } = useSidebar();
21+
22+
useEffect(() => {
23+
if (typeof window === "undefined") return undefined;
24+
const handler = (event: KeyboardEvent) => {
25+
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "b") {
26+
event.preventDefault();
27+
toggle();
28+
}
29+
};
30+
31+
window.addEventListener("keydown", handler);
32+
return () => window.removeEventListener("keydown", handler);
33+
}, [toggle]);
34+
35+
return null;
36+
};
1637

1738
interface Project {
1839
id: string;
@@ -458,23 +479,9 @@ const App: React.FC = () => {
458479
});
459480
};
460481

461-
return (
462-
<div className="h-screen flex bg-background text-foreground">
463-
<LeftSidebar
464-
projects={projects}
465-
selectedProject={selectedProject}
466-
onSelectProject={handleSelectProject}
467-
onGoHome={handleGoHome}
468-
onSelectWorkspace={handleSelectWorkspace}
469-
activeWorkspace={activeWorkspace || undefined}
470-
onReorderProjects={handleReorderProjects}
471-
onReorderProjectsFull={handleReorderProjectsFull}
472-
githubInstalled={ghInstalled}
473-
githubAuthenticated={isAuthenticated}
474-
githubUser={user}
475-
/>
476-
477-
{showHomeView ? (
482+
const renderMainContent = () => {
483+
if (showHomeView) {
484+
return (
478485
<div className="flex-1 bg-background text-foreground overflow-y-auto">
479486
<div className="container mx-auto px-4 py-8 flex flex-col justify-center min-h-screen">
480487
<div className="text-center mb-12">
@@ -526,7 +533,11 @@ const App: React.FC = () => {
526533
{null}
527534
</div>
528535
</div>
529-
) : selectedProject ? (
536+
);
537+
}
538+
539+
if (selectedProject) {
540+
return (
530541
<div className="flex-1 flex bg-background text-foreground overflow-hidden">
531542
<div className="flex-1 min-h-0 overflow-hidden flex flex-col">
532543
{activeWorkspace ? (
@@ -548,7 +559,7 @@ const App: React.FC = () => {
548559
</div>
549560

550561
{activeWorkspace && (
551-
<div className="w-80 border-l border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex flex-col h-screen max-h-screen">
562+
<div className="w-80 border-l border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex flex-col h-full max-h-full">
552563
<FileChangesPanel
553564
workspaceId={activeWorkspace.path}
554565
className="flex-1 min-h-0"
@@ -560,44 +571,71 @@ const App: React.FC = () => {
560571
</div>
561572
)}
562573
</div>
563-
) : (
564-
<div className="flex-1 bg-background text-foreground overflow-y-auto">
565-
<div className="container mx-auto px-4 py-8 flex flex-col justify-center min-h-screen">
566-
<div className="text-center mb-12">
567-
<div className="flex items-center justify-center mb-4">
568-
<img
569-
src={emdashLogo}
570-
alt="emdash"
571-
className="h-16"
572-
/>
573-
</div>
574-
<p className="text-sm sm:text-base text-gray-700 text-muted-foreground mb-6">
575-
Run multiple Coding Agents in parallel
576-
</p>
577-
<RequirementsNotice
578-
showGithubRequirement={showGithubRequirement}
579-
needsGhInstall={needsGhInstall}
580-
needsGhAuth={needsGhAuth}
581-
showAgentRequirement={showAgentRequirement}
582-
/>
583-
</div>
574+
);
575+
}
584576

585-
<div className="flex flex-col sm:flex-row gap-4 justify-center mb-8">
586-
<Button
587-
onClick={handleOpenProject}
588-
size="lg"
589-
className="min-w-[200px] bg-black text-white hover:bg-gray-800 hover:text-white border-black"
590-
>
591-
<FolderOpen className="mr-2 h-5 w-5" />
592-
Open Project
593-
</Button>
577+
return (
578+
<div className="flex-1 bg-background text-foreground overflow-y-auto">
579+
<div className="container mx-auto px-4 py-8 flex flex-col justify-center min-h-screen">
580+
<div className="text-center mb-12">
581+
<div className="flex items-center justify-center mb-4">
582+
<img
583+
src={emdashLogo}
584+
alt="emdash"
585+
className="h-16"
586+
/>
594587
</div>
588+
<p className="text-sm sm:text-base text-gray-700 text-muted-foreground mb-6">
589+
Run multiple Coding Agents in parallel
590+
</p>
591+
<RequirementsNotice
592+
showGithubRequirement={showGithubRequirement}
593+
needsGhInstall={needsGhInstall}
594+
needsGhAuth={needsGhAuth}
595+
showAgentRequirement={showAgentRequirement}
596+
/>
597+
</div>
595598

596-
{null}
599+
<div className="flex flex-col sm:flex-row gap-4 justify-center mb-8">
600+
<Button
601+
onClick={handleOpenProject}
602+
size="lg"
603+
className="min-w-[200px] bg-black text-white hover:bg-gray-800 hover:text-white border-black"
604+
>
605+
<FolderOpen className="mr-2 h-5 w-5" />
606+
Open Project
607+
</Button>
597608
</div>
609+
610+
{null}
598611
</div>
599-
)}
612+
</div>
613+
);
614+
};
600615

616+
return (
617+
<SidebarProvider>
618+
<SidebarHotkeys />
619+
<Titlebar />
620+
<div className="mt-9 flex h-[calc(100vh-36px)] w-full bg-background text-foreground overflow-hidden">
621+
<LeftSidebar
622+
projects={projects}
623+
selectedProject={selectedProject}
624+
onSelectProject={handleSelectProject}
625+
onGoHome={handleGoHome}
626+
onSelectWorkspace={handleSelectWorkspace}
627+
activeWorkspace={activeWorkspace || undefined}
628+
onReorderProjects={handleReorderProjects}
629+
onReorderProjectsFull={handleReorderProjectsFull}
630+
githubInstalled={ghInstalled}
631+
githubAuthenticated={isAuthenticated}
632+
githubUser={user}
633+
/>
634+
635+
<div className="flex-1 overflow-hidden flex flex-col">
636+
{renderMainContent()}
637+
</div>
638+
</div>
601639
<WorkspaceModal
602640
isOpen={showWorkspaceModal}
603641
onClose={() => setShowWorkspaceModal(false)}
@@ -607,7 +645,7 @@ const App: React.FC = () => {
607645
existingNames={(selectedProject?.workspaces || []).map((w) => w.name)}
608646
/>
609647
<Toaster />
610-
</div>
648+
</SidebarProvider>
611649
);
612650
};
613651

src/renderer/components/ChatInterface.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -338,16 +338,6 @@ const ChatInterface: React.FC<Props> = ({
338338
<div
339339
className={`flex flex-col h-full bg-white dark:bg-gray-800 ${className}`}
340340
>
341-
<div className="flex items-center p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
342-
<div className="flex items-center space-x-3">
343-
<Folder className="w-5 h-5 text-gray-600" />
344-
<div>
345-
<h3 className="font-medium text-gray-900 dark:text-gray-100 text-sm font-sans">
346-
{projectName}
347-
</h3>
348-
</div>
349-
</div>
350-
</div>
351341

352342
{provider === "droid" ? (
353343
<div className="flex-1 flex flex-col min-h-0">

src/renderer/components/FileChangesPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const FileChangesPanel: React.FC<FileChangesPanelProps> = ({
5555
<div
5656
className={`bg-white dark:bg-gray-800 shadow-sm flex flex-col h-full ${className}`}
5757
>
58-
<div className="px-3 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex items-center">
58+
<div className="px-3 py-2 bg-gray-50 dark:bg-gray-900 flex items-center">
5959
{hasChanges ? (
6060
<div className="flex items-center justify-between w-full">
6161
<div className="flex items-center space-x-2">

src/renderer/components/LeftSidebar.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React from "react";
22
import ReorderList from "./ReorderList";
33
import { Button } from "./ui/button";
44
import {
5-
SidebarProvider,
65
Sidebar,
76
SidebarContent,
87
SidebarGroup,
@@ -12,13 +11,14 @@ import {
1211
SidebarMenuItem,
1312
SidebarMenuButton,
1413
SidebarFooter,
14+
useSidebar,
1515
} from "./ui/sidebar";
1616
import {
1717
Collapsible,
1818
CollapsibleTrigger,
1919
CollapsibleContent,
2020
} from "./ui/collapsible";
21-
import { Home, ChevronDown } from "lucide-react";
21+
import { Home, ChevronDown} from "lucide-react";
2222
import GithubStatus from "./GithubStatus";
2323
import { WorkspaceItem } from "./WorkspaceItem";
2424

@@ -47,6 +47,22 @@ interface Workspace {
4747
agentId?: string;
4848
}
4949

50+
const SidebarToggleButton: React.FC = () => {
51+
const { toggle } = useSidebar();
52+
53+
return (
54+
<Button
55+
variant="ghost"
56+
size="icon"
57+
onClick={toggle}
58+
className="absolute -right-3 top-4 z-20 hidden h-9 w-9 items-center justify-center text-muted-foreground hover:bg-background/80 rounded-md lg:inline-flex"
59+
aria-label="Toggle sidebar"
60+
>
61+
62+
</Button>
63+
);
64+
};
65+
5066
interface LeftSidebarProps {
5167
projects: Project[];
5268
selectedProject: Project | null;
@@ -79,7 +95,7 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({
7995
);
8096

8197
return (
82-
<SidebarProvider>
98+
<div className="relative h-full">
8399
<Sidebar>
84100
<SidebarContent>
85101
<SidebarGroup className="mb-2">
@@ -91,7 +107,7 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({
91107
variant="ghost"
92108
onClick={onGoHome}
93109
aria-label="Home"
94-
className="justify-start mt-5"
110+
className="justify-start"
95111
>
96112
<Home className="w-5 h-5 sm:w-4 sm:h-4 text-gray-600 dark:text-gray-400" />
97113
<span className="hidden sm:inline text-sm font-medium">Home</span>
@@ -223,7 +239,8 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({
223239
</SidebarMenu>
224240
</SidebarFooter>
225241
</Sidebar>
226-
</SidebarProvider>
242+
<SidebarToggleButton />
243+
</div>
227244
);
228245
};
229246

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from "react";
2+
import { Button } from "../ui/button";
3+
import { PanelLeft } from "lucide-react";
4+
import { useSidebar } from "../ui/sidebar";
5+
6+
const SidebarToggleButton: React.FC = () => {
7+
const { toggle } = useSidebar();
8+
9+
return (
10+
<Button
11+
type="button"
12+
variant="ghost"
13+
size="icon"
14+
onClick={toggle}
15+
className="h-8 w-8 text-muted-foreground hover:bg-background/80 [-webkit-app-region:no-drag]"
16+
aria-label="Toggle sidebar"
17+
>
18+
<PanelLeft className="h-4 w-4" />
19+
</Button>
20+
);
21+
};
22+
23+
export default SidebarToggleButton;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from "react";
2+
import SidebarToggleButton from "./SidebarToggleButton";
3+
4+
const Titlebar: React.FC = () => {
5+
return (
6+
<header className="fixed top-0 inset-x-0 h-9 border-b border-border bg-gray-50 dark:bg-gray-900 flex items-center justify-end pr-2 [-webkit-app-region:drag]">
7+
<div className="[-webkit-app-region:no-drag]">
8+
<SidebarToggleButton />
9+
</div>
10+
</header>
11+
);
12+
};
13+
14+
export default Titlebar;

0 commit comments

Comments
 (0)