diff options
Diffstat (limited to 'extension/react-app/src/pages')
| -rw-r--r-- | extension/react-app/src/pages/gui.tsx | 107 | 
1 files changed, 65 insertions, 42 deletions
| diff --git a/extension/react-app/src/pages/gui.tsx b/extension/react-app/src/pages/gui.tsx index 70031d40..9bb558c7 100644 --- a/extension/react-app/src/pages/gui.tsx +++ b/extension/react-app/src/pages/gui.tsx @@ -6,7 +6,7 @@ import {  } from "../components";  import Loader from "../components/Loader";  import ContinueButton from "../components/ContinueButton"; -import { FullState, HighlightedRangeContext } from "../../../schema/FullState"; +import { ContextItem, FullState } from "../../../schema/FullState";  import { useCallback, useEffect, useRef, useState, useContext } from "react";  import { History } from "../../../schema/History";  import { HistoryNode } from "../../../schema/HistoryNode"; @@ -22,12 +22,16 @@ import TextDialog from "../components/TextDialog";  import HeaderButtonWithText from "../components/HeaderButtonWithText";  import ReactSwitch from "react-switch";  import { usePostHog } from "posthog-js/react"; -import { useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux";  import { RootStore } from "../redux/store";  import { postVscMessage } from "../vscode";  import UserInputContainer from "../components/UserInputContainer";  import Onboarding from "../components/Onboarding";  import { isMetaEquivalentKeyPressed } from "../util"; +import { +  setBottomMessage, +  setBottomMessageCloseTimeout, +} from "../redux/slices/uiStateSlice";  const TopGUIDiv = styled.div`    overflow: hidden; @@ -64,9 +68,6 @@ function GUI(props: GUIProps) {    const vscMachineId = useSelector(      (state: RootStore) => state.config.vscMachineId    ); -  const vscMediaUrl = useSelector( -    (state: RootStore) => state.config.vscMediaUrl -  );    const [dataSwitchChecked, setDataSwitchChecked] = useState(false);    const dataSwitchOn = useSelector(      (state: RootStore) => state.config.dataSwitchOn @@ -80,15 +81,13 @@ function GUI(props: GUIProps) {    const [waitingForSteps, setWaitingForSteps] = useState(false);    const [userInputQueue, setUserInputQueue] = useState<string[]>([]); -  const [highlightedRanges, setHighlightedRanges] = useState< -    HighlightedRangeContext[] -  >([]);    const [addingHighlightedCode, setAddingHighlightedCode] = useState(false); +  const [selectedContextItems, setSelectedContextItems] = useState< +    ContextItem[] +  >([]);    const [availableSlashCommands, setAvailableSlashCommands] = useState<      { name: string; description: string }[]    >([]); -  const [pinned, setPinned] = useState(false); -  const [showDataSharingInfo, setShowDataSharingInfo] = useState(false);    const [stepsOpen, setStepsOpen] = useState<boolean[]>([      true,      true, @@ -117,10 +116,36 @@ function GUI(props: GUIProps) {      current_index: 3,    } as any); +  const vscMediaUrl = useSelector( +    (state: RootStore) => state.config.vscMediaUrl +  );    const [showFeedbackDialog, setShowFeedbackDialog] = useState(false);    const [feedbackDialogMessage, setFeedbackDialogMessage] = useState("");    const [feedbackEntryOn, setFeedbackEntryOn] = useState(true); +  const dispatch = useDispatch(); +  const bottomMessage = useSelector( +    (state: RootStore) => state.uiState.bottomMessage +  ); + +  const [displayBottomMessageOnBottom, setDisplayBottomMessageOnBottom] = +    useState<boolean>(true); +  const mainTextInputRef = useRef<HTMLInputElement>(null); + +  const aboveComboBoxDivRef = useRef<HTMLDivElement>(null); + +  useEffect(() => { +    if (!aboveComboBoxDivRef.current) return; +    if ( +      aboveComboBoxDivRef.current.getBoundingClientRect().top > +      window.innerHeight / 2 +    ) { +      setDisplayBottomMessageOnBottom(false); +    } else { +      setDisplayBottomMessageOnBottom(true); +    } +  }, [bottomMessage, aboveComboBoxDivRef.current]); +    const topGuiDivRef = useRef<HTMLDivElement>(null);    const [scrollTimeout, setScrollTimeout] = useState<NodeJS.Timeout | null>( @@ -152,6 +177,8 @@ function GUI(props: GUIProps) {          history.timeline[history.current_index]?.active        ) {          client?.deleteAtIndex(history.current_index); +      } else if (e.key === "Escape") { +        dispatch(setBottomMessage(undefined));        }      };      window.addEventListener("keydown", listener); @@ -178,7 +205,7 @@ function GUI(props: GUIProps) {        setWaitingForSteps(waitingForSteps);        setHistory(state.history); -      setHighlightedRanges(state.highlighted_ranges); +      setSelectedContextItems(state.selected_context_items || []);        setUserInputQueue(state.user_input_queue);        setAddingHighlightedCode(state.adding_highlighted_code);        setAvailableSlashCommands( @@ -211,15 +238,6 @@ function GUI(props: GUIProps) {      scrollToBottom();    }, [waitingForSteps]); -  const mainTextInputRef = useRef<HTMLInputElement>(null); - -  const deleteContextItems = useCallback( -    (indices: number[]) => { -      client?.deleteContextAtIndices(indices); -    }, -    [client] -  ); -    const onMainTextInput = (event?: any) => {      if (mainTextInputRef.current) {        let input = (mainTextInputRef.current as any).inputValue; @@ -351,6 +369,7 @@ function GUI(props: GUIProps) {            })}          </div> +        <div ref={aboveComboBoxDivRef} />          <ComboBox            ref={mainTextInputRef}            onEnter={(e) => { @@ -360,11 +379,7 @@ function GUI(props: GUIProps) {            }}            onInputValueChange={() => {}}            items={availableSlashCommands} -          highlightedCodeSections={highlightedRanges} -          deleteContextItems={deleteContextItems} -          onTogglePin={() => { -            setPinned((prev: boolean) => !prev); -          }} +          selectedContextItems={selectedContextItems}            onToggleAddContext={() => {              client?.toggleAddingHighlightedCode();            }} @@ -373,29 +388,34 @@ function GUI(props: GUIProps) {          <ContinueButton onClick={onMainTextInput} />        </TopGUIDiv>        <div +        onMouseEnter={() => { +          dispatch(setBottomMessageCloseTimeout(undefined)); +        }} +        onMouseLeave={(e) => { +          if (!e.buttons) { +            dispatch(setBottomMessage(undefined)); +          } +        }}          style={{            position: "fixed", -          bottom: "50px", +          bottom: displayBottomMessageOnBottom ? "50px" : undefined, +          top: displayBottomMessageOnBottom ? undefined : "50px", +          left: "0", +          right: "0", +          margin: "8px", +          marginTop: "0px",            backgroundColor: vscBackground,            color: vscForeground,            borderRadius: defaultBorderRadius, -          padding: "16px", -          margin: "16px", +          padding: "12px",            zIndex: 100, -          boxShadow: `0px 0px 10px 0px ${vscForeground}`, +          boxShadow: `0px 0px 4px 0px ${vscForeground}`, +          maxHeight: "50vh", +          overflow: "scroll",          }} -        hidden={!showDataSharingInfo} +        hidden={!bottomMessage}        > -        By turning on this switch, you will begin collecting accepted and -        rejected suggestions in .continue/suggestions.json. This data is stored -        locally on your machine and not sent anywhere. -        <br /> -        <br /> -        <b> -          {dataSwitchChecked -            ? "👍 Data is being collected" -            : "👎 No data is being collected"} -        </b> +        {bottomMessage}        </div>        <Footer dataSwitchChecked={dataSwitchChecked}>          {vscMediaUrl && ( @@ -403,10 +423,13 @@ function GUI(props: GUIProps) {              href="https://github.com/continuedev/continue"              style={{ marginRight: "auto" }}            > -            <img src={`${vscMediaUrl}/continue-dev-square.png`} width="22px" /> +            <img +              src={`${vscMediaUrl}/continue-dev-square.png`} +              width="22px" +              style={{ backgroundColor: "black", color: "red" }} +            />            </a>          )} -        {/* <p style={{ margin: "0", marginRight: "auto" }}>Continue</p> */}          <HeaderButtonWithText            onClick={() => {              // Show the dialog | 
