Skip to content

Commit 57e8cbe

Browse files
committed
Hide right sidebar until there are changes or user manually opens it
1 parent e424a35 commit 57e8cbe

5 files changed

Lines changed: 127 additions & 360 deletions

File tree

apps/twig/src/renderer/components/HeaderRow.tsx

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
1+
import { useHasFileChanges } from "@features/right-sidebar/hooks/useHasFileChanges";
12
import { RightSidebarTrigger } from "@features/right-sidebar/components/RightSidebarTrigger";
23
import { useRightSidebarStore } from "@features/right-sidebar/stores/rightSidebarStore";
34
import { SidebarTrigger } from "@features/sidebar/components/SidebarTrigger";
45
import { useSidebarStore } from "@features/sidebar/stores/sidebarStore";
56
import { Box, Flex } from "@radix-ui/themes";
67
import { useHeaderStore } from "@stores/headerStore";
78
import { useNavigationStore } from "@stores/navigationStore";
9+
import type React from "react";
10+
import { useEffect } from "react";
811

912
export const HEADER_HEIGHT = 36;
1013
const COLLAPSED_WIDTH = 110;
1114

12-
export function HeaderRow() {
13-
const content = useHeaderStore((state) => state.content);
14-
const view = useNavigationStore((state) => state.view);
15-
16-
const sidebarOpen = useSidebarStore((state) => state.open);
17-
const sidebarWidth = useSidebarStore((state) => state.width);
18-
const isResizing = useSidebarStore((state) => state.isResizing);
19-
const setIsResizing = useSidebarStore((state) => state.setIsResizing);
20-
15+
function RightSidebarHeaderSection({ taskId }: { taskId: string }) {
16+
const hasChanges = useHasFileChanges(taskId);
2117
const rightSidebarOpen = useRightSidebarStore((state) => state.open);
2218
const rightSidebarWidth = useRightSidebarStore((state) => state.width);
2319
const rightSidebarIsResizing = useRightSidebarStore(
@@ -26,19 +22,71 @@ export function HeaderRow() {
2622
const setRightSidebarIsResizing = useRightSidebarStore(
2723
(state) => state.setIsResizing,
2824
);
25+
const setOpenAuto = useRightSidebarStore((state) => state.setOpenAuto);
2926

30-
const showRightSidebarSection = view.type === "task-detail";
27+
useEffect(() => {
28+
setOpenAuto(hasChanges);
29+
}, [hasChanges, setOpenAuto]);
3130

32-
const handleLeftSidebarMouseDown = (e: React.MouseEvent) => {
31+
const handleRightSidebarMouseDown = (e: React.MouseEvent) => {
3332
e.preventDefault();
34-
setIsResizing(true);
33+
setRightSidebarIsResizing(true);
3534
document.body.style.cursor = "col-resize";
3635
document.body.style.userSelect = "none";
3736
};
3837

39-
const handleRightSidebarMouseDown = (e: React.MouseEvent) => {
38+
return (
39+
<Flex
40+
align="center"
41+
justify="between"
42+
px="2"
43+
pl="3"
44+
style={{
45+
width: rightSidebarOpen
46+
? `${rightSidebarWidth}px`
47+
: `${COLLAPSED_WIDTH}px`,
48+
minWidth: `${COLLAPSED_WIDTH}px`,
49+
height: "100%",
50+
borderLeft: "1px solid var(--gray-6)",
51+
transition: rightSidebarIsResizing
52+
? "none"
53+
: "width 0.2s ease-in-out",
54+
position: "relative",
55+
}}
56+
>
57+
<RightSidebarTrigger />
58+
{rightSidebarOpen && (
59+
<Box
60+
onMouseDown={handleRightSidebarMouseDown}
61+
className="no-drag"
62+
style={{
63+
position: "absolute",
64+
left: 0,
65+
top: 0,
66+
bottom: 0,
67+
width: "4px",
68+
cursor: "col-resize",
69+
backgroundColor: "transparent",
70+
zIndex: 100,
71+
}}
72+
/>
73+
)}
74+
</Flex>
75+
);
76+
}
77+
78+
export function HeaderRow() {
79+
const content = useHeaderStore((state) => state.content);
80+
const view = useNavigationStore((state) => state.view);
81+
82+
const sidebarOpen = useSidebarStore((state) => state.open);
83+
const sidebarWidth = useSidebarStore((state) => state.width);
84+
const isResizing = useSidebarStore((state) => state.isResizing);
85+
const setIsResizing = useSidebarStore((state) => state.setIsResizing);
86+
87+
const handleLeftSidebarMouseDown = (e: React.MouseEvent) => {
4088
e.preventDefault();
41-
setRightSidebarIsResizing(true);
89+
setIsResizing(true);
4290
document.body.style.cursor = "col-resize";
4391
document.body.style.userSelect = "none";
4492
};
@@ -98,43 +146,8 @@ export function HeaderRow() {
98146
</Flex>
99147
)}
100148

101-
{showRightSidebarSection && view.type === "task-detail" && view.data && (
102-
<Flex
103-
align="center"
104-
justify="between"
105-
px="2"
106-
pl="3"
107-
style={{
108-
width: rightSidebarOpen
109-
? `${rightSidebarWidth}px`
110-
: `${COLLAPSED_WIDTH}px`,
111-
minWidth: `${COLLAPSED_WIDTH}px`,
112-
height: "100%",
113-
borderLeft: "1px solid var(--gray-6)",
114-
transition: rightSidebarIsResizing
115-
? "none"
116-
: "width 0.2s ease-in-out",
117-
position: "relative",
118-
}}
119-
>
120-
<RightSidebarTrigger />
121-
{rightSidebarOpen && (
122-
<Box
123-
onMouseDown={handleRightSidebarMouseDown}
124-
className="no-drag"
125-
style={{
126-
position: "absolute",
127-
left: 0,
128-
top: 0,
129-
bottom: 0,
130-
width: "4px",
131-
cursor: "col-resize",
132-
backgroundColor: "transparent",
133-
zIndex: 100,
134-
}}
135-
/>
136-
)}
137-
</Flex>
149+
{view.type === "task-detail" && view.data && (
150+
<RightSidebarHeaderSection taskId={view.data.id} />
138151
)}
139152
</Flex>
140153
);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { useCwd } from "@features/sidebar/hooks/useCwd";
2+
import { trpcVanilla } from "@renderer/trpc/client";
3+
import { useQuery } from "@tanstack/react-query";
4+
5+
export function useHasFileChanges(taskId: string): boolean {
6+
const repoPath = useCwd(taskId);
7+
8+
const { data: changedFiles = [] } = useQuery({
9+
queryKey: ["changed-files-head", repoPath],
10+
queryFn: () =>
11+
trpcVanilla.git.getChangedFilesHead.query({
12+
directoryPath: repoPath as string,
13+
}),
14+
enabled: !!repoPath,
15+
refetchOnMount: "always",
16+
refetchOnWindowFocus: true,
17+
placeholderData: (prev) => prev,
18+
});
19+
20+
return changedFiles.length > 0;
21+
}

apps/twig/src/renderer/features/right-sidebar/stores/rightSidebarStore.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ import { createSidebarStore } from "@stores/createSidebarStore";
33
export const useRightSidebarStore = createSidebarStore({
44
name: "right-sidebar-storage",
55
defaultWidth: 300,
6+
defaultOpen: false,
67
});

apps/twig/src/renderer/stores/createSidebarStore.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { persist } from "zustand/middleware";
33

44
export interface SidebarStoreState {
55
open: boolean;
6+
hasUserSetOpen: boolean;
67
width: number;
78
isResizing: boolean;
89
}
910

1011
export interface SidebarStoreActions {
1112
setOpen: (open: boolean) => void;
13+
setOpenAuto: (open: boolean) => void;
1214
toggle: () => void;
1315
setWidth: (width: number) => void;
1416
setIsResizing: (isResizing: boolean) => void;
@@ -29,17 +31,22 @@ export function createSidebarStore(options: CreateSidebarStoreOptions) {
2931
persist(
3032
(set) => ({
3133
open: defaultOpen,
34+
hasUserSetOpen: false,
3235
width: defaultWidth,
3336
isResizing: false,
34-
setOpen: (open) => set({ open }),
35-
toggle: () => set((state) => ({ open: !state.open })),
37+
setOpen: (open) => set({ open, hasUserSetOpen: true }),
38+
setOpenAuto: (open) =>
39+
set((state) => (state.hasUserSetOpen ? state : { open })),
40+
toggle: () =>
41+
set((state) => ({ open: !state.open, hasUserSetOpen: true })),
3642
setWidth: (width) => set({ width }),
3743
setIsResizing: (isResizing) => set({ isResizing }),
3844
}),
3945
{
4046
name,
4147
partialize: (state) => ({
4248
open: state.open,
49+
hasUserSetOpen: state.hasUserSetOpen,
4350
width: state.width,
4451
}),
4552
},

0 commit comments

Comments
 (0)