summaryrefslogtreecommitdiff
path: root/extension/react-app/src
diff options
context:
space:
mode:
Diffstat (limited to 'extension/react-app/src')
-rw-r--r--extension/react-app/src/components/CodeBlock.tsx6
-rw-r--r--extension/react-app/src/components/ComboBox.tsx15
-rw-r--r--extension/react-app/src/components/PillButton.tsx15
-rw-r--r--extension/react-app/src/components/RingLoader.tsx39
-rw-r--r--extension/react-app/src/components/StepContainer.tsx30
-rw-r--r--extension/react-app/src/components/UserInputContainer.tsx6
-rw-r--r--extension/react-app/src/hooks/useWebsocket.ts7
-rw-r--r--extension/react-app/src/pages/gui.tsx79
8 files changed, 143 insertions, 54 deletions
diff --git a/extension/react-app/src/components/CodeBlock.tsx b/extension/react-app/src/components/CodeBlock.tsx
index f51b7d9f..9909db0f 100644
--- a/extension/react-app/src/components/CodeBlock.tsx
+++ b/extension/react-app/src/components/CodeBlock.tsx
@@ -52,12 +52,12 @@ function CopyButton(props: { textToCopy: string; visible: boolean }) {
}}
>
{clicked ? (
- <CheckCircleIcon color="#00ff00" width="1.5em" height="1.5em" />
+ <CheckCircleIcon color="#00ff00" width="1.4em" height="1.4em" />
) : (
<ClipboardIcon
color={hovered ? "#00ff00" : "white"}
- width="1.5em"
- height="1.5em"
+ width="1.4em"
+ height="1.4em"
/>
)}
</StyledCopyButton>
diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx
index 9017f19c..df3f970c 100644
--- a/extension/react-app/src/components/ComboBox.tsx
+++ b/extension/react-app/src/components/ComboBox.tsx
@@ -32,7 +32,9 @@ const SEARCH_INDEX_NAME = "continue_context_items";
const mainInputFontSize = 13;
const EmptyPillDiv = styled.div`
- padding: 8px;
+ padding: 4px;
+ padding-left: 8px;
+ padding-right: 8px;
border-radius: ${defaultBorderRadius};
border: 1px dashed ${lightGray};
color: ${lightGray};
@@ -273,6 +275,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
{props.selectedContextItems.map((item, idx) => {
return (
<PillButton
+ areMultipleItems={props.selectedContextItems.length > 1}
key={`${item.description.id.item_id}${idx}`}
item={item}
warning={
@@ -301,7 +304,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
props.onToggleAddContext();
}}
>
- <DocumentPlusIcon width="1.5em" height="1.5em" />
+ <DocumentPlusIcon width="1.4em" height="1.4em" />
</HeaderButtonWithText>
))}
</div>
@@ -378,6 +381,14 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
Math.min(prev + 1, history.length)
);
setCurrentlyInContextQuery(false);
+ } else if (event.key === "Escape") {
+ setCurrentlyInContextQuery(false);
+ if (downshiftProps.isOpen) {
+ downshiftProps.closeMenu();
+ } else {
+ // Move cursor back over to the editor
+ postVscMessage("focusEditor", {});
+ }
}
},
onClick: () => {
diff --git a/extension/react-app/src/components/PillButton.tsx b/extension/react-app/src/components/PillButton.tsx
index 8e5f896e..edef808e 100644
--- a/extension/react-app/src/components/PillButton.tsx
+++ b/extension/react-app/src/components/PillButton.tsx
@@ -28,8 +28,11 @@ const Button = styled.button`
color: ${vscForeground};
background-color: ${secondaryDark};
border-radius: ${defaultBorderRadius};
- padding: 8px;
+ padding: 4px;
+ padding-left: 8px;
+ padding-right: 8px;
overflow: hidden;
+ font-size: 13px;
cursor: pointer;
`;
@@ -50,7 +53,6 @@ const GridDiv = styled.div`
const ButtonDiv = styled.div<{ backgroundColor: string }>`
background-color: ${secondaryDark};
- padding: 3px;
height: 100%;
display: flex;
align-items: center;
@@ -81,6 +83,7 @@ interface PillButtonProps {
warning?: string;
index: number;
addingHighlightedCode?: boolean;
+ areMultipleItems?: boolean;
}
const PillButton = (props: PillButtonProps) => {
@@ -100,8 +103,8 @@ const PillButton = (props: PillButtonProps) => {
<pre>
<code
style={{
- fontSize: "11px",
- backgroundColor: vscBackground,
+ fontSize: "12px",
+ backgroundColor: "transparent",
color: vscForeground,
whiteSpace: "pre-wrap",
wordWrap: "break-word",
@@ -134,8 +137,8 @@ const PillButton = (props: PillButtonProps) => {
position: "relative",
borderColor: props.warning
? "red"
- : props.item.editing
- ? "#8800aa"
+ : props.item.editing && props.areMultipleItems
+ ? vscForeground
: "transparent",
borderWidth: "1px",
borderStyle: "solid",
diff --git a/extension/react-app/src/components/RingLoader.tsx b/extension/react-app/src/components/RingLoader.tsx
new file mode 100644
index 00000000..5eb8a60f
--- /dev/null
+++ b/extension/react-app/src/components/RingLoader.tsx
@@ -0,0 +1,39 @@
+import React from "react";
+import styled, { keyframes } from "styled-components";
+import { buttonColor, vscBackground, vscForeground } from ".";
+
+const rotate = keyframes`
+ 0% {
+ stroke-dashoffset: 100;
+ }
+ 100% {
+ stroke-dashoffset: 12;
+ }
+`;
+
+const LoaderSvg = styled.svg`
+ transform: rotate(-90deg);
+ width: 40px;
+ height: 40px;
+ opacity: 50%;
+
+ circle {
+ fill: none;
+ stroke: ${vscForeground};
+ stroke-width: 2;
+ stroke-dasharray: 100;
+ stroke-dashoffset: 0;
+ animation: ${rotate} 6s ease-out infinite;
+ stroke-linecap: round;
+ }
+`;
+
+const RingLoader = () => (
+ <div className="m-auto w-full text-center">
+ <LoaderSvg viewBox="0 0 32 32">
+ <circle cx="16" cy="16" r="14" />
+ </LoaderSvg>
+ </div>
+);
+
+export default RingLoader;
diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx
index 19cdd2e1..1f999892 100644
--- a/extension/react-app/src/components/StepContainer.tsx
+++ b/extension/react-app/src/components/StepContainer.tsx
@@ -63,6 +63,14 @@ const HeaderDiv = styled.div<{ error: boolean; loading: boolean }>`
padding-right: 8px;
`;
+const LeftHeaderSubDiv = styled.div`
+ margin: 8px;
+ display: grid;
+ grid-template-columns: auto 1fr;
+ align-items: center;
+ grid-gap: 2px;
+`;
+
const ContentDiv = styled.div<{ isUserInput: boolean }>`
padding: 8px;
background-color: ${(props) =>
@@ -167,16 +175,16 @@ function StepContainer(props: StepContainerProps) {
loading={(props.historyNode.active as boolean) || false}
error={props.historyNode.observation?.error ? true : false}
>
- <div className="m-2 flex items-center">
+ <LeftHeaderSubDiv>
{!isUserInput &&
(props.open ? (
- <ChevronDownIcon width="1.5em" height="1.5em" />
+ <ChevronDownIcon width="1.4em" height="1.4em" />
) : (
- <ChevronRightIcon width="1.5em" height="1.5em" />
+ <ChevronRightIcon width="1.4em" height="1.4em" />
))}
{props.historyNode.observation?.title ||
(props.historyNode.step.name as any)}
- </div>
+ </LeftHeaderSubDiv>
{/* <HeaderButton
onClick={(e) => {
e.stopPropagation();
@@ -195,7 +203,7 @@ function StepContainer(props: StepContainerProps) {
client?.showLogsAtIndex(props.index);
}}
>
- <MagnifyingGlassIcon width="1.5em" height="1.5em" />
+ <MagnifyingGlassIcon width="1.4em" height="1.4em" />
</HeaderButtonWithText>
)}
<HeaderButtonWithText
@@ -211,14 +219,14 @@ function StepContainer(props: StepContainerProps) {
>
{props.historyNode.active ? (
<StopCircleIcon
- width="1.5em"
- height="1.5em"
+ width="1.4em"
+ height="1.4em"
onClick={props.onDelete}
/>
) : (
<XMarkIcon
- width="1.5em"
- height="1.5em"
+ width="1.4em"
+ height="1.4em"
onClick={props.onDelete}
/>
)}
@@ -232,8 +240,8 @@ function StepContainer(props: StepContainerProps) {
}}
>
<ArrowPathIcon
- width="1.5em"
- height="1.5em"
+ width="1.4em"
+ height="1.4em"
onClick={props.onRetry}
/>
</HeaderButtonWithText>
diff --git a/extension/react-app/src/components/UserInputContainer.tsx b/extension/react-app/src/components/UserInputContainer.tsx
index 25f836de..7e964ad9 100644
--- a/extension/react-app/src/components/UserInputContainer.tsx
+++ b/extension/react-app/src/components/UserInputContainer.tsx
@@ -21,6 +21,8 @@ const StyledDiv = styled.div`
align-items: center;
border-bottom: 1px solid ${vscBackground};
padding: 8px;
+ padding-top: 4px;
+ padding-bottom: 4px;
`;
const DeleteButtonDiv = styled.div`
@@ -35,7 +37,7 @@ const UserInputContainer = (props: UserInputContainerProps) => {
<StyledMarkdownPreview
light={true}
source={props.children}
- className="mr-5"
+ className="mr-6"
/>
{/* <ReactMarkdown children={props.children} className="w-fit mr-10" /> */}
<DeleteButtonDiv>
@@ -46,7 +48,7 @@ const UserInputContainer = (props: UserInputContainerProps) => {
}}
text="Delete"
>
- <XMarkIcon width="1.5em" height="1.5em" />
+ <XMarkIcon width="1.4em" height="1.4em" />
</HeaderButtonWithText>
</DeleteButtonDiv>
</StyledDiv>
diff --git a/extension/react-app/src/hooks/useWebsocket.ts b/extension/react-app/src/hooks/useWebsocket.ts
index 6b36be97..be34861b 100644
--- a/extension/react-app/src/hooks/useWebsocket.ts
+++ b/extension/react-app/src/hooks/useWebsocket.ts
@@ -25,8 +25,11 @@ function useContinueGUIProtocol(useVscodeMessagePassing: boolean = true) {
"/gui/ws?session_id=" +
encodeURIComponent(sessionId);
- console.log("Creating websocket", serverUrlWithSessionId);
- console.log("Using vscode message passing", useVscodeMessagePassing);
+ console.log(
+ "Creating GUI websocket",
+ serverUrlWithSessionId,
+ useVscodeMessagePassing
+ );
const newClient = new ContinueGUIClientProtocol(
serverUrlWithSessionId,
useVscodeMessagePassing
diff --git a/extension/react-app/src/pages/gui.tsx b/extension/react-app/src/pages/gui.tsx
index 3ae8e14e..ed73ce85 100644
--- a/extension/react-app/src/pages/gui.tsx
+++ b/extension/react-app/src/pages/gui.tsx
@@ -1,7 +1,7 @@
import styled from "styled-components";
import {
defaultBorderRadius,
- vscBackground,
+ secondaryDark,
vscForeground,
} from "../components";
import Loader from "../components/Loader";
@@ -32,11 +32,30 @@ import {
setBottomMessage,
setBottomMessageCloseTimeout,
} from "../redux/slices/uiStateSlice";
+import RingLoader from "../components/RingLoader";
const TopGUIDiv = styled.div`
overflow: hidden;
`;
+const BottomMessageDiv = styled.div<{ displayOnBottom: boolean }>`
+ position: fixed;
+ bottom: ${(props) => (props.displayOnBottom ? "50px" : undefined)};
+ top: ${(props) => (props.displayOnBottom ? undefined : "50px")};
+ left: 0;
+ right: 0;
+ margin: 8px;
+ margin-top: 0;
+ background-color: ${secondaryDark};
+ color: ${vscForeground};
+ border-radius: ${defaultBorderRadius};
+ padding: 12px;
+ z-index: 100;
+ box-shadow: 0px 0px 2px 0px ${vscForeground};
+ max-height: 50vh;
+ overflow: scroll;
+`;
+
const UserInputQueueItem = styled.div`
border-radius: ${defaultBorderRadius};
color: gray;
@@ -384,11 +403,31 @@ function GUI(props: GUIProps) {
>
{typeof client === "undefined" && (
<>
- <Loader />
- <p style={{ textAlign: "center" }}>Loading Continue server...</p>
- {/* <p style={{ textAlign: "center" }}>
- Make sure you have a folder opened in VS Code
- </p> */}
+ <RingLoader />
+ <p
+ style={{
+ textAlign: "center",
+ margin: "0px",
+ fontSize: "14px",
+ }}
+ >
+ Continue Server Starting
+ </p>
+ <p
+ style={{
+ margin: "auto",
+ textAlign: "center",
+ marginTop: "4px",
+ fontSize: "12px",
+ cursor: "pointer",
+ opacity: 0.7,
+ }}
+ onClick={() => {
+ postVscMessage("toggleDevTools", {});
+ }}
+ >
+ <u>Click to view logs</u>
+ </p>
</>
)}
{history?.timeline.map((node: HistoryNode, index: number) => {
@@ -463,7 +502,8 @@ function GUI(props: GUIProps) {
/>
<ContinueButton onClick={onMainTextInput} />
</TopGUIDiv>
- <div
+ <BottomMessageDiv
+ displayOnBottom={displayBottomMessageOnBottom}
onMouseEnter={() => {
dispatch(setBottomMessageCloseTimeout(undefined));
}}
@@ -472,27 +512,10 @@ function GUI(props: GUIProps) {
dispatch(setBottomMessage(undefined));
}
}}
- style={{
- position: "fixed",
- bottom: displayBottomMessageOnBottom ? "50px" : undefined,
- top: displayBottomMessageOnBottom ? undefined : "50px",
- left: "0",
- right: "0",
- margin: "8px",
- marginTop: "0px",
- backgroundColor: vscBackground,
- color: vscForeground,
- borderRadius: defaultBorderRadius,
- padding: "12px",
- zIndex: 100,
- boxShadow: `0px 0px 4px 0px ${vscForeground}`,
- maxHeight: "50vh",
- overflow: "scroll",
- }}
hidden={!bottomMessage}
>
{bottomMessage}
- </div>
+ </BottomMessageDiv>
<Footer dataSwitchChecked={dataSwitchChecked}>
{vscMediaUrl && (
<a
@@ -536,14 +559,14 @@ If you already have an LLM deployed on your own infrastructure, or would like to
}}
text="Clear"
>
- <TrashIcon width="1.5em" height="1.5em" />
+ <TrashIcon width="1.4em" height="1.4em" />
</HeaderButtonWithText>
<a
href="https://continue.dev/docs/how-to-use-continue"
className="no-underline"
>
<HeaderButtonWithText text="Docs">
- <BookOpenIcon width="1.5em" height="1.5em" />
+ <BookOpenIcon width="1.4em" height="1.4em" />
</HeaderButtonWithText>
</a>
<HeaderButtonWithText
@@ -557,7 +580,7 @@ If you already have an LLM deployed on your own infrastructure, or would like to
}}
text="Feedback"
>
- <ChatBubbleOvalLeftEllipsisIcon width="1.5em" height="1.5em" />
+ <ChatBubbleOvalLeftEllipsisIcon width="1.4em" height="1.4em" />
</HeaderButtonWithText>
</Footer>
</>