Skip to content

Commit fffdf68

Browse files
authored
fix: Revert the changes that made the execution mode viewer a dropdown (#727)
1 parent c232344 commit fffdf68

File tree

5 files changed

+54
-173
lines changed

5 files changed

+54
-173
lines changed

apps/twig/src/renderer/features/message-editor/components/MessageEditor.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ interface MessageEditorProps {
2727
onAttachFiles?: (files: File[]) => void;
2828
autoFocus?: boolean;
2929
currentMode?: ExecutionMode;
30-
onModeChange?: (mode: ExecutionMode) => void;
30+
onModeChange?: () => void;
3131
}
3232

3333
export const MessageEditor = forwardRef<EditorHandle, MessageEditorProps>(
@@ -208,10 +208,7 @@ export const MessageEditor = forwardRef<EditorHandle, MessageEditorProps>(
208208
</Flex>
209209
{onModeChange && currentMode && (
210210
<Flex align="center" gap="2">
211-
<ModeIndicatorInput
212-
mode={currentMode}
213-
onModeChange={onModeChange}
214-
/>
211+
<ModeIndicatorInput mode={currentMode} />
215212
<DiffStatsIndicator repoPath={repoPath} />
216213
</Flex>
217214
)}
Lines changed: 33 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,9 @@
1-
import { useSettingsStore } from "@features/settings/stores/settingsStore";
2-
import { useCwd } from "@features/sidebar/hooks/useCwd";
3-
import {
4-
Circle,
5-
LockOpen,
6-
Pause,
7-
Pencil,
8-
ShieldCheck,
9-
} from "@phosphor-icons/react";
10-
import { Flex, Select, Text } from "@radix-ui/themes";
11-
import { trpcVanilla } from "@renderer/trpc";
12-
import { EXECUTION_MODES, type ExecutionMode } from "@shared/types";
13-
import { useQuery } from "@tanstack/react-query";
1+
import { LockOpen, Pause, Pencil, ShieldCheck } from "@phosphor-icons/react";
2+
import { Flex, Text } from "@radix-ui/themes";
3+
import type { ExecutionMode } from "@shared/types";
144

155
interface ModeIndicatorInputProps {
166
mode: ExecutionMode;
17-
taskId?: string;
18-
onModeChange: (mode: ExecutionMode) => void;
197
}
208

219
const modeConfig: Record<
@@ -28,146 +16,55 @@ const modeConfig: Record<
2816
> = {
2917
plan: {
3018
label: "plan mode on",
31-
icon: <Pause size={12} weight="bold" color="var(--amber-11)" />,
19+
icon: <Pause size={12} weight="bold" />,
3220
colorVar: "var(--amber-11)",
3321
},
3422
default: {
3523
label: "default mode",
36-
icon: <Pencil size={12} color="var(--gray-11)" />,
24+
icon: <Pencil size={12} />,
3725
colorVar: "var(--gray-11)",
3826
},
3927
acceptEdits: {
4028
label: "auto-accept edits",
41-
icon: <ShieldCheck size={12} weight="fill" color="var(--green-11)" />,
29+
icon: <ShieldCheck size={12} weight="fill" />,
4230
colorVar: "var(--green-11)",
4331
},
4432
bypassPermissions: {
4533
label: "bypass permissions",
46-
icon: <LockOpen size={12} weight="bold" color="var(--red-11)" />,
34+
icon: <LockOpen size={12} weight="bold" />,
4735
colorVar: "var(--red-11)",
4836
},
4937
};
5038

51-
export function ModeIndicatorInput({
52-
mode,
53-
onModeChange,
54-
taskId,
55-
}: ModeIndicatorInputProps) {
39+
export function ModeIndicatorInput({ mode }: ModeIndicatorInputProps) {
5640
const config = modeConfig[mode];
57-
const repoPath = useCwd(taskId ?? "");
58-
const allowBypassPermissions = useSettingsStore(
59-
(s) => s.allowBypassPermissions,
60-
);
61-
62-
const availableModes = allowBypassPermissions
63-
? EXECUTION_MODES
64-
: EXECUTION_MODES.filter((m) => m !== "bypassPermissions");
65-
66-
const { data: diffStats } = useQuery({
67-
queryKey: ["diff-stats", repoPath],
68-
queryFn: () =>
69-
trpcVanilla.git.getDiffStats.query({
70-
directoryPath: repoPath as string,
71-
}),
72-
enabled: !!repoPath && !!taskId,
73-
staleTime: 5000,
74-
refetchInterval: 5000,
75-
placeholderData: (prev) => prev,
76-
});
77-
78-
const hasDiffStats = diffStats && diffStats.filesChanged > 0;
7941

8042
return (
81-
<Select.Root value={mode} onValueChange={onModeChange} size="1">
82-
<Select.Trigger
83-
className="w-fit"
84-
onClick={(e) => {
85-
e.stopPropagation();
86-
}}
87-
>
88-
<Flex align="center" gap="1">
43+
<Flex align="center" justify="between" py="1">
44+
<Flex align="center" gap="1">
45+
<Text
46+
size="1"
47+
style={{
48+
color: config.colorVar,
49+
fontFamily: "monospace",
50+
display: "flex",
51+
alignItems: "center",
52+
gap: "4px",
53+
}}
54+
>
8955
{config.icon}
90-
<Text
91-
size="1"
92-
style={{
93-
color: config.colorVar,
94-
fontFamily: "monospace",
95-
}}
96-
>
97-
{config.label}
98-
</Text>
99-
<Text
100-
size="1"
101-
style={{
102-
color: "var(--gray-9)",
103-
fontFamily: "monospace",
104-
}}
105-
>
106-
(shift+tab to cycle)
107-
</Text>
108-
{hasDiffStats && (
109-
<Text
110-
size="1"
111-
style={{
112-
color: "var(--gray-9)",
113-
fontFamily: "monospace",
114-
display: "flex",
115-
alignItems: "center",
116-
gap: "6px",
117-
}}
118-
>
119-
<Circle size={4} weight="fill" style={{ margin: "0 4px" }} />
120-
<span style={{ color: "var(--gray-11)" }}>
121-
{diffStats.filesChanged}{" "}
122-
{diffStats.filesChanged === 1 ? "file" : "files"}
123-
</span>
124-
<span style={{ color: "var(--green-9)" }}>
125-
+{diffStats.linesAdded}
126-
</span>
127-
<span style={{ color: "var(--red-9)" }}>
128-
-{diffStats.linesRemoved}
129-
</span>
130-
</Text>
131-
)}
132-
</Flex>
133-
</Select.Trigger>
134-
<Select.Content>
135-
{availableModes.map((modeOption) => {
136-
const optionConfig = modeConfig[modeOption];
137-
const hoverBgClass =
138-
modeOption === "plan"
139-
? "hover:!bg-[var(--amber-11)]"
140-
: modeOption === "default"
141-
? "hover:!bg-[var(--gray-11)]"
142-
: modeOption === "acceptEdits"
143-
? "hover:!bg-[var(--green-11)]"
144-
: "hover:!bg-[var(--red-11)]";
145-
return (
146-
<Select.Item
147-
key={modeOption}
148-
value={modeOption}
149-
className={`group transition-colors ${hoverBgClass}`}
150-
>
151-
<Flex
152-
align="center"
153-
gap="1"
154-
className="group-hover:!text-[black] [&_svg]:group-hover:!text-[black] [&_svg]:group-hover:!fill-[black] [&_svg_path]:group-hover:!fill-[black] [&_svg_path]:group-hover:!stroke-[black]"
155-
style={{
156-
color: optionConfig.colorVar,
157-
fontFamily: "monospace",
158-
}}
159-
>
160-
<span className="group-hover:[&_svg]:!text-[black] group-hover:[&_svg]:!fill-[black] group-hover:[&_svg_path]:!fill-[black] group-hover:[&_svg_path]:!stroke-[black]">
161-
{optionConfig.icon}
162-
</span>
163-
<Text size="1" className="group-hover:!text-[black]">
164-
{optionConfig.label}
165-
</Text>
166-
</Flex>
167-
</Select.Item>
168-
);
169-
})}
170-
</Select.Content>
171-
</Select.Root>
56+
{config.label}
57+
</Text>
58+
<Text
59+
size="1"
60+
style={{
61+
color: "var(--gray-9)",
62+
fontFamily: "monospace",
63+
}}
64+
>
65+
(shift+tab to cycle)
66+
</Text>
67+
</Flex>
68+
</Flex>
17269
);
17370
}

apps/twig/src/renderer/features/sessions/components/SessionView.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,11 @@ export function SessionView({
8888
}
8989
}, [allowBypassPermissions, currentMode, taskId, isCloud, setSessionMode]);
9090

91-
const handleModeChange = useCallback(
92-
(mode: ExecutionMode) => {
93-
if (!taskId || isCloud) return;
94-
setSessionMode(taskId, mode);
95-
},
96-
[taskId, isCloud, setSessionMode],
97-
);
91+
const handleModeChange = useCallback(() => {
92+
if (!taskId || isCloud) return;
93+
const nextMode = cycleExecutionMode(currentMode, allowBypassPermissions);
94+
setSessionMode(taskId, nextMode);
95+
}, [taskId, isCloud, currentMode, allowBypassPermissions, setSessionMode]);
9896

9997
const sessionId = taskId ?? "default";
10098
const setContext = useDraftStore((s) => s.actions.setContext);

apps/twig/src/renderer/features/task-detail/components/TaskInput.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { TorchGlow } from "@components/TorchGlow";
22
import { FolderPicker } from "@features/folder-picker/components/FolderPicker";
33
import type { MessageEditorHandle } from "@features/message-editor/components/MessageEditor";
4-
import type { ExecutionMode } from "@features/sessions/stores/sessionStore";
4+
import {
5+
cycleExecutionMode,
6+
type ExecutionMode,
7+
} from "@features/sessions/stores/sessionStore";
58
import { useSettingsStore } from "@features/settings/stores/settingsStore";
69
import { useRepositoryIntegration } from "@hooks/useIntegrations";
710
import { Flex } from "@radix-ui/themes";
@@ -43,9 +46,11 @@ export function TaskInput() {
4346
}
4447
}, [allowBypassPermissions, executionMode]);
4548

46-
const handleModeChange = useCallback((mode: ExecutionMode) => {
47-
setExecutionMode(mode);
48-
}, []);
49+
const handleModeChange = useCallback(() => {
50+
setExecutionMode((current) =>
51+
cycleExecutionMode(current, allowBypassPermissions),
52+
);
53+
}, [allowBypassPermissions]);
4954

5055
const { githubIntegration } = useRepositoryIntegration();
5156

apps/twig/src/renderer/features/task-detail/components/TaskInputEditor.tsx

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ import { EditorToolbar } from "@features/message-editor/components/EditorToolbar
33
import type { MessageEditorHandle } from "@features/message-editor/components/MessageEditor";
44
import { ModeIndicatorInput } from "@features/message-editor/components/ModeIndicatorInput";
55
import { useTiptapEditor } from "@features/message-editor/tiptap/useTiptapEditor";
6-
import {
7-
cycleExecutionMode,
8-
type ExecutionMode,
9-
} from "@features/sessions/stores/sessionStore";
10-
import { useSettingsStore } from "@features/settings/stores/settingsStore";
6+
import type { ExecutionMode } from "@features/sessions/stores/sessionStore";
117
import { useConnectivity } from "@hooks/useConnectivity";
128
import { ArrowUp } from "@phosphor-icons/react";
139
import { Box, Flex, IconButton, Text, Tooltip } from "@radix-ui/themes";
@@ -27,7 +23,7 @@ interface TaskInputEditorProps {
2723
hasDirectory: boolean;
2824
onEmptyChange?: (isEmpty: boolean) => void;
2925
executionMode: ExecutionMode;
30-
onModeChange: (mode: ExecutionMode) => void;
26+
onModeChange: () => void;
3127
}
3228

3329
export const TaskInputEditor = forwardRef<
@@ -52,26 +48,19 @@ export const TaskInputEditor = forwardRef<
5248
const isCloudMode = runMode === "cloud";
5349
const { isOnline } = useConnectivity();
5450
const isDisabled = isCreatingTask || !isOnline;
55-
const { allowBypassPermissions } = useSettingsStore();
5651

5752
useHotkeys(
5853
"shift+tab",
5954
(e) => {
6055
e.preventDefault();
61-
onModeChange(cycleExecutionMode(executionMode, allowBypassPermissions));
56+
onModeChange();
6257
},
6358
{
6459
enableOnFormTags: true,
6560
enableOnContentEditable: true,
6661
enabled: !isCreatingTask && !isCloudMode,
6762
},
68-
[
69-
onModeChange,
70-
executionMode,
71-
allowBypassPermissions,
72-
isCreatingTask,
73-
isCloudMode,
74-
],
63+
[onModeChange, isCreatingTask, isCloudMode],
7564
);
7665

7766
const {
@@ -245,12 +234,7 @@ export const TaskInputEditor = forwardRef<
245234
</Flex>
246235
</Flex>
247236
</Flex>
248-
{!isCloudMode && (
249-
<ModeIndicatorInput
250-
mode={executionMode}
251-
onModeChange={onModeChange}
252-
/>
253-
)}
237+
{!isCloudMode && <ModeIndicatorInput mode={executionMode} />}
254238
</>
255239
);
256240
},

0 commit comments

Comments
 (0)