summaryrefslogtreecommitdiff
path: root/extension/react-app/src/tabs/gui.tsx
diff options
context:
space:
mode:
authorNate Sesti <sestinj@gmail.com>2023-06-26 16:39:07 -0700
committerNate Sesti <sestinj@gmail.com>2023-06-26 16:39:07 -0700
commit0b3e6fdf553a481bdd899a2608376dbb95c8e72e (patch)
tree615381124b54fb8a10523335c971b5a2d208b767 /extension/react-app/src/tabs/gui.tsx
parentdeca77889cfc8eaa4065694f113525eda365e5d0 (diff)
parent0862b388dc0f07e45b6daeaec1f8c05925623692 (diff)
downloadsncontinue-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.tsx149
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>