From f48854157efed4275ecc23152a7e3027fec9105c Mon Sep 17 00:00:00 2001
From: Nate Sesti <sestinj@gmail.com>
Date: Mon, 12 Jun 2023 21:30:49 -0700
Subject: slash commands dropdown!

---
 extension/react-app/src/tabs/gui.tsx | 296 ++++++++++++++++++-----------------
 1 file changed, 153 insertions(+), 143 deletions(-)

(limited to 'extension/react-app/src/tabs/gui.tsx')

diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index cb7a5440..1569c178 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -12,7 +12,8 @@ import { History } from "../../../schema/History";
 import { HistoryNode } from "../../../schema/HistoryNode";
 import StepContainer from "../components/StepContainer";
 import useContinueGUIProtocol from "../hooks/useWebsocket";
-import { Trash } from "@styled-icons/heroicons-outline";
+import { BookOpen, Trash } from "@styled-icons/heroicons-outline";
+import ComboBox from "../components/ComboBox";
 let TopGUIDiv = styled.div`
   display: grid;
   grid-template-columns: 1fr;
@@ -42,128 +43,132 @@ interface GUIProps {
 function GUI(props: GUIProps) {
   const [waitingForSteps, setWaitingForSteps] = useState(false);
   const [userInputQueue, setUserInputQueue] = useState<string[]>([]);
-  const [history, setHistory] = useState<History | undefined>({
-    timeline: [
-      {
-        step: {
-          name: "Waiting for user input",
-          cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-          description:
-            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and ```\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3",
-        },
-        observation: {
-          title: "ERROR FOUND",
-          error:
-            "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
-        },
-        output: [
-          {
-            traceback: {
-              frames: [
-                {
-                  filepath:
-                    "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-                  lineno: 7,
-                  function: "<module>",
-                  code: "print(sum(first, second))",
-                },
-              ],
-              message: "unsupported operand type(s) for +: 'int' and 'str'",
-              error_type:
-                '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError',
-              full_traceback:
-                "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
-            },
-          },
-          null,
-        ],
-      },
-      {
-        step: {
-          name: "EditCodeStep",
-          range_in_files: [
-            {
-              filepath:
-                "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-              range: {
-                start: {
-                  line: 0,
-                  character: 0,
-                },
-                end: {
-                  line: 6,
-                  character: 25,
-                },
-              },
-            },
-          ],
-          prompt:
-            "I ran into this problem with my Python code:\n\n                Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'\n\n                Below are the files that might need to be fixed:\n\n                {code}\n\n                This is what the code should be in order to avoid the problem:\n",
-          description:
-            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and\n```python\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3",
-        },
-        output: [
-          null,
-          {
-            reversible: true,
-            actions: [
-              {
-                reversible: true,
-                filesystem: {},
-                filepath:
-                  "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-                range: {
-                  start: {
-                    line: 0,
-                    character: 0,
-                  },
-                  end: {
-                    line: 6,
-                    character: 25,
-                  },
-                },
-                replacement:
-                  "\nfrom sum import sum\n\nfirst = 1\nsecond = 2\n\nprint(sum(first, second))",
-              },
-            ],
-          },
-        ],
-      },
-      {
-        step: {
-          name: "SolveTracebackStep",
-          traceback: {
-            frames: [
-              {
-                filepath:
-                  "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-                lineno: 7,
-                function: "<module>",
-                code: "print(sum(first, second))",
-              },
-            ],
-            message: "unsupported operand type(s) for +: 'int' and 'str'",
-            error_type:
-              '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError',
-            full_traceback:
-              "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
-          },
-          description: "Running step: SolveTracebackStep",
-        },
-        output: [null, null],
-      },
-      {
-        step: {
-          name: "RunCodeStep",
-          cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-          description:
-            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py`",
-        },
-        output: [null, null],
-      },
-    ],
-    current_index: 3,
-  } as any);
+  const [availableSlashCommands, setAvailableSlashCommands] = useState<
+    { name: string; description: string }[]
+  >([]);
+  const [history, setHistory] = useState<History | undefined>();
+  // {
+  //   timeline: [
+  //     {
+  //       step: {
+  //         name: "Waiting for user input",
+  //         cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+  //         description:
+  //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and ```\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3",
+  //       },
+  //       observation: {
+  //         title: "ERROR FOUND",
+  //         error:
+  //           "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
+  //       },
+  //       output: [
+  //         {
+  //           traceback: {
+  //             frames: [
+  //               {
+  //                 filepath:
+  //                   "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+  //                 lineno: 7,
+  //                 function: "<module>",
+  //                 code: "print(sum(first, second))",
+  //               },
+  //             ],
+  //             message: "unsupported operand type(s) for +: 'int' and 'str'",
+  //             error_type:
+  //               '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError',
+  //             full_traceback:
+  //               "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
+  //           },
+  //         },
+  //         null,
+  //       ],
+  //     },
+  //     {
+  //       step: {
+  //         name: "EditCodeStep",
+  //         range_in_files: [
+  //           {
+  //             filepath:
+  //               "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+  //             range: {
+  //               start: {
+  //                 line: 0,
+  //                 character: 0,
+  //               },
+  //               end: {
+  //                 line: 6,
+  //                 character: 25,
+  //               },
+  //             },
+  //           },
+  //         ],
+  //         prompt:
+  //           "I ran into this problem with my Python code:\n\n                Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'\n\n                Below are the files that might need to be fixed:\n\n                {code}\n\n                This is what the code should be in order to avoid the problem:\n",
+  //         description:
+  //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and\n```python\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3",
+  //       },
+  //       output: [
+  //         null,
+  //         {
+  //           reversible: true,
+  //           actions: [
+  //             {
+  //               reversible: true,
+  //               filesystem: {},
+  //               filepath:
+  //                 "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+  //               range: {
+  //                 start: {
+  //                   line: 0,
+  //                   character: 0,
+  //                 },
+  //                 end: {
+  //                   line: 6,
+  //                   character: 25,
+  //                 },
+  //               },
+  //               replacement:
+  //                 "\nfrom sum import sum\n\nfirst = 1\nsecond = 2\n\nprint(sum(first, second))",
+  //             },
+  //           ],
+  //         },
+  //       ],
+  //     },
+  //     {
+  //       step: {
+  //         name: "SolveTracebackStep",
+  //         traceback: {
+  //           frames: [
+  //             {
+  //               filepath:
+  //                 "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+  //               lineno: 7,
+  //               function: "<module>",
+  //               code: "print(sum(first, second))",
+  //             },
+  //           ],
+  //           message: "unsupported operand type(s) for +: 'int' and 'str'",
+  //           error_type:
+  //             '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError',
+  //           full_traceback:
+  //             "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
+  //         },
+  //         description: "Running step: SolveTracebackStep",
+  //       },
+  //       output: [null, null],
+  //     },
+  //     {
+  //       step: {
+  //         name: "RunCodeStep",
+  //         cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+  //         description:
+  //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py`",
+  //       },
+  //       output: [null, null],
+  //     },
+  //   ],
+  //   current_index: 3,
+  // } as any);
 
   const topGuiDivRef = useRef<HTMLDivElement>(null);
   const client = useContinueGUIProtocol();
@@ -197,13 +202,24 @@ function GUI(props: GUIProps) {
 
       scrollToBottom();
     });
+    client?.onAvailableSlashCommands((commands) => {
+      console.log("Received available slash commands: ", commands);
+      setAvailableSlashCommands(
+        commands.map((c) => {
+          return {
+            name: "/" + c.name,
+            description: c.description,
+          };
+        })
+      );
+    });
   }, [client]);
 
   useEffect(() => {
     scrollToBottom();
   }, [waitingForSteps]);
 
-  const mainTextInputRef = useRef<HTMLTextAreaElement>(null);
+  const mainTextInputRef = useRef<HTMLInputElement>(null);
 
   useEffect(() => {
     if (mainTextInputRef.current) {
@@ -246,8 +262,6 @@ function GUI(props: GUIProps) {
           return [...queue, input];
         });
       }
-      mainTextInputRef.current.value = "";
-      mainTextInputRef.current.style.height = "";
     }
 
     setWaitingForSteps(true);
@@ -270,7 +284,12 @@ function GUI(props: GUIProps) {
       }}
     >
       <TopBar>
-        <h3>Continue</h3>
+        <a href="https://continue.dev/docs" className="no-underline">
+          <HeaderButton style={{ padding: "3px" }}>
+            Continue Docs
+            <BookOpen size="1.6em" />
+          </HeaderButton>
+        </a>
         <HeaderButton style={{ padding: "3px" }}>
           Clear History
           <Trash
@@ -323,7 +342,7 @@ function GUI(props: GUIProps) {
         })}
       </div>
 
-      <MainTextInput
+      <ComboBox
         disabled={
           history
             ? history.timeline[history.current_index].step.name ===
@@ -331,22 +350,13 @@ function GUI(props: GUIProps) {
             : false
         }
         ref={mainTextInputRef}
-        onKeyDown={(e) => {
-          if (e.key === "Enter") {
-            onMainTextInput();
-            e.stopPropagation();
-            e.preventDefault();
-          }
-        }}
-        rows={1}
-        onChange={() => {
-          const textarea = mainTextInputRef.current!;
-          textarea.style.height = ""; /* Reset the height*/
-          textarea.style.height = `${Math.min(
-            textarea.scrollHeight - 15,
-            500
-          )}px`;
+        onEnter={(e) => {
+          onMainTextInput();
+          e.stopPropagation();
+          e.preventDefault();
         }}
+        onInputValueChange={() => {}}
+        items={availableSlashCommands}
       />
       <ContinueButton onClick={onMainTextInput} />
     </TopGUIDiv>
-- 
cgit v1.2.3-70-g09d2

