Skip to content

Commit 6a17462

Browse files
Move project switcher into activity rail
Add the project switcher as the first activity rail item and remove the title-bar project switcher path. Drop the obsolete title-bar project mode setting and make rail expansion snap instead of animating layout width.
1 parent 1fe69b7 commit 6a17462

9 files changed

Lines changed: 66 additions & 57 deletions

File tree

src/features/file-system/stores/file-system.store.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -555,11 +555,7 @@ export const useFileSystemStore = createSelectors(
555555
const hasOpenWorkspace =
556556
!!get().rootFolderPath || useWorkspaceTabsStore.getState().projectTabs.length > 0;
557557

558-
if (
559-
settings.openFoldersInNewWindow &&
560-
settings.titleBarProjectMode === "window" &&
561-
hasOpenWorkspace
562-
) {
558+
if (settings.openFoldersInNewWindow && hasOpenWorkspace) {
563559
await createAppWindow({
564560
path: selected,
565561
isDirectory: true,

src/features/file-system/stores/recent-folders.store.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,7 @@ export const useRecentFoldersStore = create<RecentFoldersState & RecentFoldersAc
9494
return;
9595
}
9696

97-
if (
98-
settings.openFoldersInNewWindow &&
99-
settings.titleBarProjectMode === "window" &&
100-
hasOpenWorkspace
101-
) {
97+
if (settings.openFoldersInNewWindow && hasOpenWorkspace) {
10298
await createAppWindow({
10399
path: folderPath,
104100
isDirectory: true,

src/features/layout/components/sidebar/main-sidebar.tsx

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
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";
17
import { memo, type ReactNode } from "react";
28
import { CollaborationSidebarView } from "@/features/collaboration/components/collaboration-sidebar";
39
import { DockerSidebar } from "@/features/docker/components/docker-sidebar";
@@ -12,9 +18,11 @@ import { OutlineSidebar } from "@/features/outline/components/outline-sidebar";
1218
import { useSettingsStore } from "@/features/settings/stores/settings.store";
1319
import { useBufferStore } from "@/features/editor/stores/buffer.store";
1420
import { useUIState } from "@/features/window/stores/ui-state.store";
21+
import { useWorkspaceTabsStore } from "@/features/window/stores/workspace-tabs.store";
1522
import { useAuthStore } from "@/features/window/stores/auth.store";
1623
import { useExtensionViews } from "@/extensions/ui/hooks/use-extension-views";
1724
import { ExtensionErrorBoundary } from "@/extensions/ui/components/extension-error-boundary";
25+
import { Button } from "@/ui/button";
1826
import { SidebarPanel } from "@/ui/sidebar";
1927
import { 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+
3797
export 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}

src/features/settings/components/tabs/appearance-settings.tsx

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export const AppearanceSettings = () => {
3333
openFoldersInNewWindow: state.settings.openFoldersInNewWindow,
3434
syncSystemTheme: state.settings.syncSystemTheme,
3535
theme: state.settings.theme,
36-
titleBarProjectMode: state.settings.titleBarProjectMode,
3736
uiFontFamily: state.settings.uiFontFamily,
3837
uiFontSize: state.settings.uiFontSize,
3938
windowTransparency: state.settings.windowTransparency,
@@ -43,11 +42,6 @@ export const AppearanceSettings = () => {
4342
const registeredThemes = useRegisteredThemes();
4443
const registeredIconThemes = useRegisteredIconThemes();
4544

46-
const titleBarProjectModeOptions = [
47-
{ value: "tabs", label: "Tabs" },
48-
{ value: "window", label: "Window" },
49-
];
50-
5145
const themeOptions = useMemo(
5246
() =>
5347
registeredThemes.map((theme) => ({
@@ -348,29 +342,9 @@ export const AppearanceSettings = () => {
348342
/>
349343
</SettingRow>
350344

351-
<SettingRow
352-
label="Title Bar Project Mode"
353-
description="Show project tabs or a single window-style title in the custom title bar"
354-
onReset={() =>
355-
updateSetting("titleBarProjectMode", getDefaultSetting("titleBarProjectMode"))
356-
}
357-
canReset={settings.titleBarProjectMode !== getDefaultSetting("titleBarProjectMode")}
358-
>
359-
<Select
360-
value={settings.titleBarProjectMode}
361-
options={titleBarProjectModeOptions}
362-
onChange={(value) => updateSetting("titleBarProjectMode", value as "tabs" | "window")}
363-
className={SETTINGS_CONTROL_WIDTHS.default}
364-
size="md"
365-
variant="default"
366-
searchable
367-
searchableTrigger="input"
368-
/>
369-
</SettingRow>
370-
371345
<SettingRow
372346
label="Open Projects In New Window"
373-
description="In window title mode, opening another folder uses a separate window when a project is already open"
347+
description="Opening another folder uses a separate window when a project is already open"
374348
onReset={() =>
375349
updateSetting("openFoldersInNewWindow", getDefaultSetting("openFoldersInNewWindow"))
376350
}

src/features/settings/config/default-settings.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ export const defaultSettings: Settings = {
6262
nativeMenuBar: false,
6363
compactMenuBar: true,
6464
windowTransparency: true,
65-
titleBarProjectMode: "window",
6665
headerTrailingItemsOrder: [...HEADER_TRAILING_ITEM_IDS],
6766
sidebarActivityItemsOrder: [...SIDEBAR_ACTIVITY_ITEM_IDS],
6867
footerLeadingItemsOrder: [...FOOTER_LEADING_ITEM_IDS],

src/features/settings/config/search-index.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -418,14 +418,6 @@ export const settingsSearchIndex: SettingSearchRecord[] = [
418418
description: "Use translucent app chrome and transparent native windows where supported",
419419
keywords: ["window", "transparency", "transparent", "translucent", "glass", "chrome"],
420420
},
421-
{
422-
id: "appearance-title-bar-project-mode",
423-
tab: "appearance",
424-
section: "Layout",
425-
label: "Title Bar Project Mode",
426-
description: "Show project tabs or a single window-style title in the custom title bar",
427-
keywords: ["title", "bar", "project", "tabs", "window", "mode"],
428-
},
429421
{
430422
id: "appearance-open-folders-new-window",
431423
tab: "appearance",

src/features/settings/lib/settings-sync.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ type SyncableSettingsKey =
4646
| "autoThemeDark"
4747
| "compactMenuBar"
4848
| "windowTransparency"
49-
| "titleBarProjectMode"
5049
| "headerTrailingItemsOrder"
5150
| "sidebarActivityItemsOrder"
5251
| "footerLeadingItemsOrder"
@@ -138,7 +137,6 @@ const SYNCABLE_SETTINGS_KEYS: SyncableSettingsKey[] = [
138137
"autoThemeDark",
139138
"compactMenuBar",
140139
"windowTransparency",
141-
"titleBarProjectMode",
142140
"headerTrailingItemsOrder",
143141
"sidebarActivityItemsOrder",
144142
"footerLeadingItemsOrder",

src/features/settings/types/settings.types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ export interface Settings {
6767
nativeMenuBar: boolean;
6868
compactMenuBar: boolean;
6969
windowTransparency: boolean;
70-
titleBarProjectMode: "tabs" | "window";
7170
headerTrailingItemsOrder: HeaderTrailingItemId[];
7271
sidebarActivityItemsOrder: Array<SidebarActivityItemId | string>;
7372
footerLeadingItemsOrder: FooterLeadingItemId[];

src/features/window/components/title-bar/custom-title-bar.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import { AccountMenu } from "../account-menu";
3232
import ProjectPicker from "../project-picker";
3333
import RunActionsButton from "../run-actions-button";
3434
import { type HeaderItem, orderHeaderItems, placeHeaderItemsBeforeAccount } from "./header-items";
35-
import { TitleBarProjectArea } from "./title-bar-project-area";
3635
import { WindowControls } from "./window-controls";
3736
import WindowMenuBar from "../window-menu-bar";
3837

@@ -43,7 +42,6 @@ interface CustomTitleBarProps {
4342

4443
const CustomTitleBar = ({ showMinimal = false }: CustomTitleBarProps) => {
4544
const nativeMenuBar = useSettingsStore((state) => state.settings.nativeMenuBar);
46-
const titleBarProjectMode = useSettingsStore((state) => state.settings.titleBarProjectMode);
4745
const compactMenuBar = useSettingsStore((state) => state.settings.compactMenuBar);
4846
const isAIChatVisible = useSettingsStore((state) => state.settings.isAIChatVisible);
4947
const headerTrailingItemsOrder = useSettingsStore(
@@ -331,8 +329,6 @@ const CustomTitleBar = ({ showMinimal = false }: CustomTitleBarProps) => {
331329
{sidebarToggle}
332330
</div>
333331

334-
<TitleBarProjectArea mode={titleBarProjectMode} />
335-
336332
{/* Account menu */}
337333
<div className="flex h-8 items-center">
338334
<div className="flex items-center gap-1">
@@ -369,9 +365,6 @@ const CustomTitleBar = ({ showMinimal = false }: CustomTitleBarProps) => {
369365
</div>
370366
</div>
371367
</div>
372-
373-
<TitleBarProjectArea mode={titleBarProjectMode} />
374-
375368
{/* Right side */}
376369
<div className="z-20 flex items-center">
377370
<div className="flex items-center gap-1">

0 commit comments

Comments
 (0)