Skip to content

Commit d6b9dcb

Browse files
authored
Merge pull request #4939 from continuedev/dallin/assistant-select
Assistant select and Notch UI tweaks
2 parents 9e3e28d + 65d43c2 commit d6b9dcb

File tree

13 files changed

+230
-240
lines changed

13 files changed

+230
-240
lines changed

gui/src/components/mainInput/ContinueInputBox.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Editor, JSONContent } from "@tiptap/react";
22
import { ContextItemWithId, InputModifiers } from "core";
3-
import { useMemo, useState } from "react";
3+
import { useMemo } from "react";
44
import styled, { keyframes } from "styled-components";
55
import { defaultBorderRadius, vscBackground } from "..";
66
import { useAppSelector } from "../../redux/hooks";
@@ -113,12 +113,10 @@ function ContinueInputBox(props: ContinueInputBoxProps) {
113113
}
114114
: {};
115115

116-
const [lumpOpen, setLumpOpen] = useState(true);
117-
118116
return (
119117
<div className={`${props.hidden ? "hidden" : ""}`}>
120118
<div className={`relative flex flex-col px-2`}>
121-
{props.isMainInput && <Lump open={lumpOpen} setOpen={setLumpOpen} />}
119+
{props.isMainInput && <Lump />}
122120
<GradientBorder
123121
loading={isStreaming && props.isLastUserInput ? 1 : 0}
124122
borderColor={
@@ -135,8 +133,6 @@ function ContinueInputBox(props: ContinueInputBoxProps) {
135133
availableSlashCommands={filteredSlashCommands}
136134
historyKey={historyKey}
137135
toolbarOptions={toolbarOptions}
138-
lumpOpen={lumpOpen}
139-
setLumpOpen={setLumpOpen}
140136
inputId={props.inputId}
141137
/>
142138
</GradientBorder>

gui/src/components/mainInput/InputToolbar.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { ToolTip } from "../gui/Tooltip";
3131
import ModelSelect from "../modelSelection/ModelSelect";
3232
import ModeSelect from "../modelSelection/ModeSelect";
3333
import { useFontSize } from "../ui/font";
34-
import HoverItem from "./InputToolbar/bottom/HoverItem";
34+
import HoverItem from "./InputToolbar/HoverItem";
3535

3636
const StyledDiv = styled.div<{ isHidden?: boolean }>`
3737
padding-top: 4px;
@@ -87,8 +87,6 @@ interface InputToolbarProps {
8787
toolbarOptions?: ToolbarOptions;
8888
disabled?: boolean;
8989
isMainInput?: boolean;
90-
lumpOpen: boolean;
91-
setLumpOpen: (open: boolean) => void;
9290
}
9391

9492
function InputToolbar(props: InputToolbarProps) {

gui/src/components/mainInput/InputToolbar/bottom/ToolDropdownItem.tsx renamed to gui/src/components/mainInput/InputToolbar/ToolDropdownItem.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { InformationCircleIcon } from "@heroicons/react/24/outline";
22
import { Tool } from "core";
33
import { useEffect } from "react";
44
import { useDispatch } from "react-redux";
5-
import { useAppSelector } from "../../../../redux/hooks";
6-
import { addTool, toggleToolSetting } from "../../../../redux/slices/uiSlice";
7-
import { fontSize } from "../../../../util";
8-
import { ToolTip } from "../../../gui/Tooltip";
5+
import { useAppSelector } from "../../../redux/hooks";
6+
import { addTool, toggleToolSetting } from "../../../redux/slices/uiSlice";
7+
import { fontSize } from "../../../util";
8+
import { ToolTip } from "../../gui/Tooltip";
99

1010
interface ToolDropdownItemProps {
1111
tool: Tool;

gui/src/components/mainInput/InputToolbar/bottom/ToolPermissionsDialog.tsx renamed to gui/src/components/mainInput/InputToolbar/ToolPermissionsDialog.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { Tool } from "core";
22
import { useMemo } from "react";
3-
import { useAppDispatch, useAppSelector } from "../../../../redux/hooks";
4-
import { toggleToolGroupSetting } from "../../../../redux/slices/uiSlice";
5-
import { fontSize } from "../../../../util";
6-
import ToggleSwitch from "../../../gui/Switch";
3+
import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
4+
import { toggleToolGroupSetting } from "../../../redux/slices/uiSlice";
5+
import { fontSize } from "../../../util";
6+
import ToggleSwitch from "../../gui/Switch";
77
import ToolDropdownItem from "./ToolDropdownItem";
88

99
export const ToolPermissionsDialog = () => {

gui/src/components/mainInput/InputToolbar/top/TopInputToolbar.tsx

Lines changed: 0 additions & 22 deletions
This file was deleted.

gui/src/components/mainInput/Lump/BlockSettingsTopToolbar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
1313
import { toggleBlockSettingsToolbar } from "../../../redux/slices/uiSlice";
1414
import { fontSize } from "../../../util";
1515
import AssistantSelect from "../../modelSelection/platform/AssistantSelect";
16-
import HoverItem from "../InputToolbar/bottom/HoverItem";
16+
import HoverItem from "../InputToolbar/HoverItem";
1717

1818
interface BlockSettingsToolbarIcon {
1919
tooltip: string;
@@ -129,7 +129,7 @@ export function BlockSettingsTopToolbar(props: BlockSettingsTopToolbarProps) {
129129
</div>
130130
</div>
131131
</div>
132-
<div className="ml-auto">
132+
<div>
133133
<AssistantSelect />
134134
</div>
135135
</div>

gui/src/components/mainInput/Lump/index.tsx

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,7 @@ import { useAppSelector } from "../../../redux/hooks";
99
import { LumpToolbar } from "./LumpToolbar";
1010
import { SelectedSection } from "./sections/SelectedSection";
1111

12-
interface LumpProps {
13-
open: boolean;
14-
setOpen: (open: boolean) => void;
15-
}
16-
17-
const LumpDiv = styled.div<{ open: boolean }>`
12+
const LumpDiv = styled.div`
1813
background-color: ${vscInputBackground};
1914
margin-left: 4px;
2015
margin-right: 4px;
@@ -35,33 +30,50 @@ const ContentDiv = styled.div<{ hasSection: boolean; isVisible: boolean }>`
3530
overflow-y: auto;
3631
`;
3732

38-
export function Lump(props: LumpProps) {
39-
const { open, setOpen } = props;
33+
export function Lump() {
4034
const [selectedSection, setSelectedSection] = useState<string | null>(null);
4135
const [displayedSection, setDisplayedSection] = useState<string | null>(null);
4236
const [isVisible, setIsVisible] = useState(false);
4337
const isStreaming = useAppSelector((state) => state.session.isStreaming);
4438

39+
useEffect(() => {
40+
if (!selectedSection) {
41+
return;
42+
}
43+
const handleKeyDown = (event: KeyboardEvent) => {
44+
if (event.key === "Escape") {
45+
setSelectedSection(null);
46+
}
47+
};
48+
document.addEventListener("keydown", handleKeyDown);
49+
return () => {
50+
document.removeEventListener("keydown", handleKeyDown);
51+
};
52+
}, [selectedSection]);
53+
54+
useEffect(() => {
55+
if (isStreaming) {
56+
setSelectedSection(null);
57+
}
58+
}, [isStreaming]);
59+
4560
useEffect(() => {
4661
if (selectedSection) {
4762
setDisplayedSection(selectedSection);
4863
setIsVisible(true);
4964
} else {
5065
setIsVisible(false);
51-
// Delay clearing the displayed section until after the fade-out
5266
const timeout = setTimeout(() => {
5367
setDisplayedSection(null);
54-
}, 300); // Match the transition duration
55-
return () => clearTimeout(timeout);
68+
}, 300);
69+
return () => {
70+
clearTimeout(timeout);
71+
};
5672
}
5773
}, [selectedSection]);
5874

59-
if (!open) {
60-
return null;
61-
}
62-
6375
return (
64-
<LumpDiv open={open}>
76+
<LumpDiv>
6577
<div className="mt-0.5 px-2">
6678
<LumpToolbar
6779
selectedSection={selectedSection}
@@ -73,9 +85,7 @@ export function Lump(props: LumpProps) {
7385
hasSection={!!selectedSection}
7486
isVisible={isVisible}
7587
>
76-
{!isStreaming && (
77-
<SelectedSection selectedSection={displayedSection} />
78-
)}
88+
<SelectedSection selectedSection={displayedSection} />
7989
</ContentDiv>
8090
</div>
8191
</LumpDiv>

gui/src/components/mainInput/Lump/sections/ToolsSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ToolPermissionsDialog } from "../../InputToolbar/bottom/ToolPermissionsDialog";
1+
import { ToolPermissionsDialog } from "../../InputToolbar/ToolPermissionsDialog";
22

33
interface ToolsSectionProps {}
44

gui/src/components/mainInput/tiptap/TipTapEditor.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ export interface TipTapEditorProps {
3232
) => void;
3333
editorState?: JSONContent;
3434
toolbarOptions?: ToolbarOptions;
35-
lumpOpen: boolean;
36-
setLumpOpen: (open: boolean) => void;
3735
placeholder?: string;
3836
historyKey: string;
3937
inputId: string;
@@ -262,8 +260,6 @@ function TipTapEditor(props: TipTapEditorProps) {
262260
activeKey={activeKey}
263261
hidden={shouldHideToolbar && !props.isMainInput}
264262
onAddContextItem={() => insertCharacterWithWhitespace("@")}
265-
lumpOpen={props.lumpOpen}
266-
setLumpOpen={props.setLumpOpen}
267263
onEnter={onEnterRef.current}
268264
onImageFileSelected={(file) => {
269265
handleImageFile(ideMessenger, file).then((result) => {

gui/src/components/modelSelection/platform/AssistantSelect.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import {
22
ArrowTopRightOnSquareIcon,
33
BuildingOfficeIcon,
4+
CheckIcon,
45
ChevronDownIcon,
56
Cog6ToothIcon,
67
ExclamationTriangleIcon,
78
PlusIcon,
89
} from "@heroicons/react/24/outline";
9-
import { useContext, useEffect, useMemo, useRef, useState } from "react";
10+
import { useContext, useEffect, useMemo, useRef } from "react";
1011
import { useAuth } from "../../../context/Auth";
1112
import { IdeMessengerContext } from "../../../context/IdeMessenger";
1213
import { cycleProfile, selectProfileThunk } from "../../../redux";
@@ -35,14 +36,16 @@ import AssistantIcon from "./AssistantIcon";
3536

3637
interface AssistantSelectOptionProps {
3738
profile: ProfileDescription;
39+
selected: boolean;
3840
onClick: () => void;
3941
}
42+
4043
const AssistantSelectOption = ({
4144
profile,
45+
selected,
4246
onClick,
4347
}: AssistantSelectOptionProps) => {
4448
const navigate = useNavigate();
45-
const [hovered, setHovered] = useState(false);
4649

4750
const hasFatalErrors = useMemo(() => {
4851
return !!profile.errors?.find((error) => error.fatal);
@@ -72,29 +75,29 @@ const AssistantSelectOption = ({
7275

7376
return (
7477
<ListboxOption
75-
onMouseEnter={() => setHovered(true)}
76-
onMouseLeave={() => setHovered(false)}
7778
value={profile.id}
7879
disabled={hasFatalErrors}
7980
onClick={!hasFatalErrors ? handleOptionClick : undefined}
8081
fontSizeModifier={-2}
8182
>
8283
<div className="flex w-full flex-col gap-0.5">
8384
<div className="flex w-full items-center justify-between">
84-
<div className="flex w-full items-center">
85+
<div className="flex w-full items-center gap-2">
8586
<div className="mr-2 h-4 w-4 flex-shrink-0">
8687
<AssistantIcon assistant={profile} />
8788
</div>
88-
<span className="line-clamp-1 flex-1">{profile.title}</span>
89+
<span
90+
className={`line-clamp-1 flex-1 ${selected ? "font-bold" : ""}`}
91+
>
92+
{profile.title}
93+
</span>
8994
</div>
90-
<div className="ml-2 flex items-center">
95+
<div className="flex flex-row items-center gap-2">
96+
<div>{selected ? <CheckIcon className="h-3 w-3" /> : null}</div>
9197
{!profile.errors?.length ? (
9298
isLocalProfile(profile) ? (
9399
<Cog6ToothIcon
94100
className="h-3 w-3 flex-shrink-0 cursor-pointer"
95-
style={{
96-
opacity: hovered ? 1 : 0,
97-
}}
98101
onClick={(e) => {
99102
e.stopPropagation();
100103
e.preventDefault();
@@ -103,9 +106,6 @@ const AssistantSelectOption = ({
103106
/>
104107
) : (
105108
<ArrowTopRightOnSquareIcon
106-
style={{
107-
opacity: hovered ? 1 : 0,
108-
}}
109109
className="h-3 w-3 flex-shrink-0 cursor-pointer"
110110
onClick={(e) => {
111111
e.stopPropagation();
@@ -215,7 +215,7 @@ export default function AssistantSelect() {
215215

216216
return (
217217
<Listbox>
218-
<div className="sm:max-w-4/5 relative flex">
218+
<div className="relative">
219219
<ListboxButton
220220
data-testid="assistant-select-button"
221221
ref={buttonRef}
@@ -249,6 +249,7 @@ export default function AssistantSelect() {
249249
key={idx}
250250
profile={profile}
251251
onClick={close}
252+
selected={profile.id === selectedProfile.id}
252253
/>
253254
);
254255
})}

gui/src/components/ui/Listbox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const ListboxOptions = React.forwardRef<HTMLUListElement, ListboxOptionsProps>(
4646
anchor={"bottom start"}
4747
{...props}
4848
className={cn(
49-
"bg-vsc-input-background flex flex-col overflow-auto px-0 shadow-md",
49+
"bg-vsc-input-background flex w-max min-w-[160px] max-w-[400px] flex-col overflow-auto px-0 shadow-md",
5050
props.className,
5151
)}
5252
style={{

0 commit comments

Comments
 (0)