diff options
author | Nate Sesti <sestinj@gmail.com> | 2023-06-26 16:39:07 -0700 |
---|---|---|
committer | Nate Sesti <sestinj@gmail.com> | 2023-06-26 16:39:07 -0700 |
commit | 0b3e6fdf553a481bdd899a2608376dbb95c8e72e (patch) | |
tree | 615381124b54fb8a10523335c971b5a2d208b767 /extension/react-app/src/tabs/gui.tsx | |
parent | deca77889cfc8eaa4065694f113525eda365e5d0 (diff) | |
parent | 0862b388dc0f07e45b6daeaec1f8c05925623692 (diff) | |
download | sncontinue-0b3e6fdf553a481bdd899a2608376dbb95c8e72e.tar.gz sncontinue-0b3e6fdf553a481bdd899a2608376dbb95c8e72e.tar.bz2 sncontinue-0b3e6fdf553a481bdd899a2608376dbb95c8e72e.zip |
Merge branch 'main' into styled-code
Diffstat (limited to 'extension/react-app/src/tabs/gui.tsx')
-rw-r--r-- | extension/react-app/src/tabs/gui.tsx | 149 |
1 files changed, 123 insertions, 26 deletions
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx index 624d22d5..13b74423 100644 --- a/extension/react-app/src/tabs/gui.tsx +++ b/extension/react-app/src/tabs/gui.tsx @@ -1,11 +1,5 @@ import styled from "styled-components"; -import { - defaultBorderRadius, - vscBackground, - Loader, - MainTextInput, - HeaderButton, -} from "../components"; +import { defaultBorderRadius, Loader } from "../components"; import ContinueButton from "../components/ContinueButton"; import { useCallback, useEffect, useRef, useState } from "react"; import { History } from "../../../schema/History"; @@ -20,6 +14,11 @@ import { import ComboBox from "../components/ComboBox"; 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 { RootStore } from "../redux/store"; +import LoadingCover from "../components/LoadingCover"; const TopGUIDiv = styled.div` overflow: hidden; @@ -33,7 +32,7 @@ const UserInputQueueItem = styled.div` text-align: center; `; -const Footer = styled.footer` +const Footer = styled.footer<{ dataSwitchChecked: boolean }>` display: flex; flex-direction: row; gap: 8px; @@ -42,6 +41,8 @@ const Footer = styled.footer` align-items: center; margin-top: 8px; border-top: 0.1px solid gray; + background-color: ${(props) => + props.dataSwitchChecked ? "#12887a33" : "transparent"}; `; interface GUIProps { @@ -49,14 +50,22 @@ interface GUIProps { } function GUI(props: GUIProps) { + const posthog = usePostHog(); + const vscMachineId = useSelector( + (state: RootStore) => state.config.vscMachineId + ); + + const [usingFastModel, setUsingFastModel] = useState(false); const [waitingForSteps, setWaitingForSteps] = useState(false); const [userInputQueue, setUserInputQueue] = useState<string[]>([]); const [availableSlashCommands, setAvailableSlashCommands] = useState< { name: string; description: string }[] >([]); + const [dataSwitchChecked, setDataSwitchChecked] = useState(false); + const [showDataSharingInfo, setShowDataSharingInfo] = useState(false); const [stepsOpen, setStepsOpen] = useState<boolean[]>([]); const [history, setHistory] = useState<History | undefined>(); - // { + // { // timeline: [ // { // step: { @@ -144,6 +153,7 @@ function GUI(props: GUIProps) { // ], // }, // { + // active: false, // step: { // name: "SolveTracebackStep", // traceback: { @@ -204,24 +214,41 @@ function GUI(props: GUIProps) { }, [topGuiDivRef.current, scrollTimeout]); useEffect(() => { + const listener = (e: any) => { + // Cmd + J to toggle fast model + if (e.key === "i" && e.metaKey && e.shiftKey) { + setUsingFastModel((prev) => !prev); + } + }; + window.addEventListener("keydown", listener); + + return () => { + window.removeEventListener("keydown", listener); + }; + }, []); + + useEffect(() => { console.log("CLIENT ON STATE UPDATE: ", client, client?.onStateUpdate); client?.onStateUpdate((state) => { // Scroll only if user is at very bottom of the window. + setUsingFastModel(state.default_model === "gpt-3.5-turbo"); const shouldScrollToBottom = topGuiDivRef.current && topGuiDivRef.current?.offsetHeight - window.scrollY < 100; setWaitingForSteps(state.active); setHistory(state.history); setUserInputQueue(state.user_input_queue); - const nextStepsOpen = [...stepsOpen]; - for ( - let i = nextStepsOpen.length; - i < state.history.timeline.length; - i++ - ) { - nextStepsOpen.push(true); - } - setStepsOpen(nextStepsOpen); + setStepsOpen((prev) => { + const nextStepsOpen = [...prev]; + for ( + let i = nextStepsOpen.length; + i < state.history.timeline.length; + i++ + ) { + nextStepsOpen.push(true); + } + return nextStepsOpen; + }); if (shouldScrollToBottom) { scrollToBottom(); @@ -263,8 +290,9 @@ function GUI(props: GUIProps) { const onMainTextInput = () => { if (mainTextInputRef.current) { - if (!client) return; let input = mainTextInputRef.current.value; + mainTextInputRef.current.value = ""; + if (!client) return; if ( history?.timeline.length && @@ -301,6 +329,7 @@ function GUI(props: GUIProps) { // const iterations = useSelector(selectIterations); return ( <> + <LoadingCover hidden={true} message="Downloading local model..." /> <TextDialog showDialog={showFeedbackDialog} onEnter={(text) => { @@ -323,9 +352,7 @@ function GUI(props: GUIProps) { {typeof client === "undefined" && ( <> <Loader></Loader> - <p style={{ textAlign: "center" }}> - Trying to reconnect with server... - </p> + <p style={{ textAlign: "center" }}>Loading Continue server...</p> </> )} {history?.timeline.map((node: HistoryNode, index: number) => { @@ -340,7 +367,7 @@ function GUI(props: GUIProps) { setStepsOpen(nextStepsOpen); }} onToggleAll={() => { - setStepsOpen((prev) => prev.map(() => !prev[index])); + setStepsOpen((prev) => prev.map((_, index) => !prev[index])); }} key={index} onUserInput={(input: string) => { @@ -390,17 +417,87 @@ function GUI(props: GUIProps) { /> <ContinueButton onClick={onMainTextInput} /> </TopGUIDiv> - <Footer> + <div + style={{ + position: "fixed", + bottom: "50px", + backgroundColor: "white", + color: "black", + borderRadius: defaultBorderRadius, + padding: "16px", + margin: "16px", + }} + hidden={!showDataSharingInfo} + > + By turning on this switch, you signal that you would contribute this + software development data to a publicly accessible, open-source dataset + in the future. + <br /> + <br /> + <b> + {dataSwitchChecked + ? "No data is being collected. In the future, you would be contributing data" + : "No data is being collected. In the future, your data would not be shared"} + </b> + </div> + <Footer dataSwitchChecked={dataSwitchChecked}> + <div + style={{ + display: "flex", + gap: "4px", + marginRight: "auto", + alignItems: "center", + }} + onMouseEnter={() => { + setShowDataSharingInfo(true); + }} + onMouseLeave={() => { + setShowDataSharingInfo(false); + }} + > + <ReactSwitch + height={20} + handleDiameter={20} + width={40} + onChange={() => { + posthog?.capture("data_switch_toggled", { + vscMachineId: vscMachineId, + dataSwitchChecked: !dataSwitchChecked, + }); + setDataSwitchChecked((prev) => !prev); + }} + onColor="#12887a" + checked={dataSwitchChecked} + /> + <span style={{ cursor: "help", fontSize: "14px" }}> + Contribute Data + </span> + </div> + <HeaderButtonWithText + onClick={() => { + client?.changeDefaultModel( + usingFastModel ? "gpt-4" : "gpt-3.5-turbo" + ); + setUsingFastModel((prev) => !prev); + }} + text={usingFastModel ? "gpt-3.5-turbo" : "gpt-4"} + > + <div + style={{ fontSize: "18px", marginLeft: "2px", marginRight: "2px" }} + > + {usingFastModel ? "⚡" : "🧠"} + </div> + </HeaderButtonWithText> <HeaderButtonWithText onClick={() => { client?.sendClear(); }} - text="Clear History" + text="Clear All" > <Trash size="1.6em" /> </HeaderButtonWithText> <a href="https://continue.dev/docs" className="no-underline"> - <HeaderButtonWithText text="Continue Docs"> + <HeaderButtonWithText text="Docs"> <BookOpen size="1.6em" /> </HeaderButtonWithText> </a> |