diff options
Diffstat (limited to 'extension/react-app/src')
| -rw-r--r-- | extension/react-app/src/components/CodeBlock.tsx | 6 | ||||
| -rw-r--r-- | extension/react-app/src/components/ComboBox.tsx | 15 | ||||
| -rw-r--r-- | extension/react-app/src/components/PillButton.tsx | 15 | ||||
| -rw-r--r-- | extension/react-app/src/components/RingLoader.tsx | 39 | ||||
| -rw-r--r-- | extension/react-app/src/components/StepContainer.tsx | 30 | ||||
| -rw-r--r-- | extension/react-app/src/components/UserInputContainer.tsx | 6 | ||||
| -rw-r--r-- | extension/react-app/src/hooks/useWebsocket.ts | 7 | ||||
| -rw-r--r-- | extension/react-app/src/pages/gui.tsx | 79 | 
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>      </> | 
