1+ import { convertFileSrc } from "@tauri-apps/api/core" ;
2+ import {
3+ FolderIcon as Folder ,
4+ HardDrivesIcon as HardDrives ,
5+ PlusIcon as Plus ,
6+ } from "@phosphor-icons/react" ;
17import { memo , type ReactNode } from "react" ;
28import { CollaborationSidebarView } from "@/features/collaboration/components/collaboration-sidebar" ;
39import { DockerSidebar } from "@/features/docker/components/docker-sidebar" ;
@@ -12,9 +18,11 @@ import { OutlineSidebar } from "@/features/outline/components/outline-sidebar";
1218import { useSettingsStore } from "@/features/settings/stores/settings.store" ;
1319import { useBufferStore } from "@/features/editor/stores/buffer.store" ;
1420import { useUIState } from "@/features/window/stores/ui-state.store" ;
21+ import { useWorkspaceTabsStore } from "@/features/window/stores/workspace-tabs.store" ;
1522import { useAuthStore } from "@/features/window/stores/auth.store" ;
1623import { useExtensionViews } from "@/extensions/ui/hooks/use-extension-views" ;
1724import { ExtensionErrorBoundary } from "@/extensions/ui/components/extension-error-boundary" ;
25+ import { Button } from "@/ui/button" ;
1826import { SidebarPanel } from "@/ui/sidebar" ;
1927import { cn } from "@/utils/cn" ;
2028
@@ -34,6 +42,58 @@ interface SidebarActivityRailProps {
3442 expanded ?: boolean ;
3543}
3644
45+ const getProjectNameFromPath = ( path ?: string ) => {
46+ if ( ! path ) return "Open Project" ;
47+ const parts = path . split ( / [ \\ / ] / ) . filter ( Boolean ) ;
48+ return parts [ parts . length - 1 ] || path ;
49+ } ;
50+
51+ const isRemoteProjectPath = ( path ?: string ) => path ?. startsWith ( "remote://" ) === true ;
52+
53+ function SidebarProjectSwitcher ( { expanded } : { expanded : boolean } ) {
54+ const rootFolderPath = useFileSystemStore ( ( state ) => state . rootFolderPath ) ;
55+ const projectTabs = useWorkspaceTabsStore . use . projectTabs ( ) ;
56+ const setIsProjectPickerVisible = useUIState ( ( state ) => state . setIsProjectPickerVisible ) ;
57+ const activeProject = projectTabs . find ( ( tab ) => tab . isActive ) ;
58+ const projectName = activeProject ?. name || getProjectNameFromPath ( rootFolderPath ) ;
59+ const projectPath = activeProject ?. path || rootFolderPath ;
60+ const customIcon = activeProject ?. customIcon ;
61+ const isRemote = isRemoteProjectPath ( projectPath ) ;
62+
63+ const icon = customIcon ? (
64+ < img
65+ src = { convertFileSrc ( customIcon ) }
66+ alt = ""
67+ className = "size-4 shrink-0 rounded-[var(--app-radius-control-sm)] object-contain"
68+ />
69+ ) : isRemote ? (
70+ < HardDrives className = "size-4" weight = "duotone" />
71+ ) : projectPath ? (
72+ < Folder className = "size-4" weight = "duotone" />
73+ ) : (
74+ < Plus className = "size-4" weight = "duotone" />
75+ ) ;
76+
77+ return (
78+ < Button
79+ type = "button"
80+ variant = "ghost"
81+ tooltip = { expanded ? undefined : projectName }
82+ tooltipSide = "right"
83+ onClick = { ( ) => setIsProjectPickerVisible ( true ) }
84+ className = { cn (
85+ expanded
86+ ? "h-9 w-full justify-start gap-2 px-2.5"
87+ : "min-h-6 min-w-7 rounded-[var(--app-radius-control-sm)] px-0" ,
88+ ) }
89+ aria-label = "Switch project"
90+ >
91+ { icon }
92+ { expanded ? < span className = "min-w-0 truncate" > { projectName } </ span > : null }
93+ </ Button >
94+ ) ;
95+ }
96+
3797export const SidebarActivityRail = memo ( ( { expanded = false } : SidebarActivityRailProps ) => {
3898 const isGitViewActive = useUIState ( ( state ) => state . isGitViewActive ) ;
3999 const isGitHubPRsViewActive = useUIState ( ( state ) => state . isGitHubPRsViewActive ) ;
@@ -54,10 +114,12 @@ export const SidebarActivityRail = memo(({ expanded = false }: SidebarActivityRa
54114 return (
55115 < div
56116 className = { cn (
57- "athas-sidebar-rail flex shrink-0 items-start pb-1.5 transition-[width] duration-[var(--app-duration-fast)] ease-[var(--app-ease-smooth)] " ,
117+ "athas-sidebar-rail flex shrink-0 flex-col items-start pb-1.5" ,
58118 expanded ? "w-40 px-1.5 pt-1" : "w-[3.5rem] px-0.5 pt-1" ,
59119 ) }
60120 >
121+ < SidebarProjectSwitcher expanded = { expanded } />
122+ < div className = { cn ( "my-1 h-px shrink-0 bg-border/60" , expanded ? "w-full" : "mx-auto w-7" ) } />
61123 < SidebarPaneSelector
62124 activeSidebarView = { activeSidebarView }
63125 isGitViewActive = { isGitViewActive }
0 commit comments