From f9a84bd2d65b3142cbcfcdd8e1e9394c9d4b458e Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Sun, 24 Sep 2023 01:00:42 -0700
Subject: feat: :lipstick: more ui improvements
---
.../src/components/HeaderButtonWithText.tsx | 8 +++--
extension/react-app/src/components/Layout.tsx | 6 ++--
extension/react-app/src/components/PillButton.tsx | 1 +
extension/react-app/src/components/Suggestions.tsx | 30 +++++++++++--------
.../src/components/UserInputContainer.tsx | 35 ++++++++++++++++++----
extension/react-app/src/components/index.ts | 2 +-
6 files changed, 57 insertions(+), 25 deletions(-)
(limited to 'extension/react-app/src/components')
diff --git a/extension/react-app/src/components/HeaderButtonWithText.tsx b/extension/react-app/src/components/HeaderButtonWithText.tsx
index ca359250..84e6118c 100644
--- a/extension/react-app/src/components/HeaderButtonWithText.tsx
+++ b/extension/react-app/src/components/HeaderButtonWithText.tsx
@@ -13,7 +13,10 @@ interface HeaderButtonWithTextProps {
onKeyDown?: (e: any) => void;
}
-const HeaderButtonWithText = (props: HeaderButtonWithTextProps) => {
+const HeaderButtonWithText = React.forwardRef<
+ HTMLButtonElement,
+ HeaderButtonWithTextProps
+>((props: HeaderButtonWithTextProps, ref) => {
const [hover, setHover] = useState(false);
const tooltipPortalDiv = document.getElementById("tooltip-portal-div");
@@ -35,6 +38,7 @@ const HeaderButtonWithText = (props: HeaderButtonWithTextProps) => {
onClick={props.onClick}
onKeyDown={props.onKeyDown}
className={props.className}
+ ref={ref}
>
{props.children}
@@ -47,6 +51,6 @@ const HeaderButtonWithText = (props: HeaderButtonWithTextProps) => {
)}
>
);
-};
+});
export default HeaderButtonWithText;
diff --git a/extension/react-app/src/components/Layout.tsx b/extension/react-app/src/components/Layout.tsx
index 9ec2e671..6dbd348f 100644
--- a/extension/react-app/src/components/Layout.tsx
+++ b/extension/react-app/src/components/Layout.tsx
@@ -2,7 +2,7 @@ import styled from "styled-components";
import { defaultBorderRadius, secondaryDark, vscForeground } from ".";
import { Outlet } from "react-router-dom";
import TextDialog from "./TextDialog";
-import { useContext, useEffect, useState } from "react";
+import { useContext, useEffect } from "react";
import { GUIClientContext } from "../App";
import { useDispatch, useSelector } from "react-redux";
import { RootStore } from "../redux/store";
@@ -12,8 +12,6 @@ import {
setShowDialog,
} from "../redux/slices/uiStateSlice";
import {
- PlusIcon,
- FolderIcon,
SparklesIcon,
Cog6ToothIcon,
QuestionMarkCircleIcon,
@@ -22,6 +20,7 @@ import HeaderButtonWithText from "./HeaderButtonWithText";
import { useNavigate, useLocation } from "react-router-dom";
import ModelSelect from "./ModelSelect";
import ProgressBar from "./ProgressBar";
+import { temporarilyClearSession } from "../redux/slices/serverStateReducer";
// #region Styled Components
const FOOTER_HEIGHT = "1.8em";
@@ -112,6 +111,7 @@ const Layout = () => {
event.code === "KeyN" &&
timeline.filter((n) => !n.step.hide).length > 0
) {
+ dispatch(temporarilyClearSession(false));
client?.loadSession(undefined);
}
if ((event.metaKey || event.ctrlKey) && event.code === "KeyC") {
diff --git a/extension/react-app/src/components/PillButton.tsx b/extension/react-app/src/components/PillButton.tsx
index 4b602619..4e13428d 100644
--- a/extension/react-app/src/components/PillButton.tsx
+++ b/extension/react-app/src/components/PillButton.tsx
@@ -196,6 +196,7 @@ const PillButton = (props: PillButtonProps) => {
<>
Ask a question
,
-
- - Highlight code in the editor
- - Press cmd+M to select the code
- - Ask a question
-
,
-
- - Highlight code in the editor
- - Press cmd+shift+M to select the code
- - Request and edit
-
,
+
+ 1. Highlight code in the editor
+
+ 2. Press cmd+M to select the code
+
+ 3. Ask a question
+
,
+
+ 1. Highlight code in the editor
+
+ 2. Press cmd+shift+M to select the code
+
+ 3. Request an edit
+
,
];
const suggestionsStages: any[][] = [
@@ -178,7 +182,7 @@ function SuggestionsArea(props: { onClick: (textInput: string) => void }) {
const inputs = timeline.filter(
(node) => !node.step.hide && node.step.name === "User Input"
);
- return inputs.length - numTutorialInputs === 0;
+ return inputs.length - numTutorialInputs <= 0;
}, [timeline, numTutorialInputs]);
return (
@@ -187,9 +191,9 @@ function SuggestionsArea(props: { onClick: (textInput: string) => void }) {
- Tutorial
+ Tutorial ({stage + 1}/3)
-
+
{stage < suggestionsStages.length &&
suggestionsStages[stage][0]?.title}
diff --git a/extension/react-app/src/components/UserInputContainer.tsx b/extension/react-app/src/components/UserInputContainer.tsx
index 76a3c615..15f1752f 100644
--- a/extension/react-app/src/components/UserInputContainer.tsx
+++ b/extension/react-app/src/components/UserInputContainer.tsx
@@ -103,7 +103,7 @@ const StyledDiv = styled.div<{ editing: boolean }>`
z-index: 1;
overflow: hidden;
display: grid;
- grid-template-columns: auto 1fr;
+ grid-template-columns: 1fr auto;
outline: ${(props) => (props.editing ? `1px solid ${lightGray}` : "none")};
cursor: text;
@@ -114,7 +114,7 @@ const DeleteButtonDiv = styled.div`
top: 8px;
right: 8px;
background-color: ${secondaryDark};
- box-shadow: 2px 2px 10px ${secondaryDark};
+ box-shadow: 4px 4px 10px ${secondaryDark};
border-radius: ${defaultBorderRadius};
`;
@@ -123,6 +123,7 @@ const GridDiv = styled.div`
grid-template-columns: auto 1fr;
grid-gap: 8px;
align-items: center;
+ width: 100%;
`;
function stringWithEllipsis(str: string, maxLen: number) {
@@ -165,7 +166,7 @@ const UserInputContainer = (props: UserInputContainerProps) => {
divRef.current.innerText = prevContent;
divRef.current.blur();
}
- }, [divRef.current]);
+ }, [divRef.current, prevContent]);
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
@@ -190,6 +191,10 @@ const UserInputContainer = (props: UserInputContainerProps) => {
divRef.current?.blur();
};
+ const [divTextContent, setDivTextContent] = useState("");
+
+ const checkButtonRef = useRef(null);
+
return (
{
padding: "8px",
paddingTop: "4px",
paddingBottom: "4px",
+ width: "100%",
}}
>
{
- onBlur();
+ onBlur={(e) => {
+ if (e.relatedTarget !== checkButtonRef.current) onBlur();
}}
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey) {
@@ -256,6 +262,9 @@ const UserInputContainer = (props: UserInputContainerProps) => {
doneEditing(e);
}
}}
+ onInput={(e) => {
+ setDivTextContent((e.target as any).innerText);
+ }}
contentEditable={true}
suppressContentEditableWarning={true}
className="mr-6 ml-1 cursor-text w-full py-2 flex items-center content-center outline-none"
@@ -271,10 +280,24 @@ const UserInputContainer = (props: UserInputContainerProps) => {
{
doneEditing(e);
+ e.stopPropagation();
}}
text="Done"
+ disabled={
+ divTextContent === "" || divTextContent === prevContent
+ }
+ ref={checkButtonRef}
>
-
+
) : (
<>
diff --git a/extension/react-app/src/components/index.ts b/extension/react-app/src/components/index.ts
index 6f5a2f37..510740f8 100644
--- a/extension/react-app/src/components/index.ts
+++ b/extension/react-app/src/components/index.ts
@@ -178,7 +178,7 @@ export const HeaderButton = styled.button<{ inverted: boolean | undefined }>`
border: none;
border-radius: ${defaultBorderRadius};
- cursor: pointer;
+ cursor: ${({ disabled }) => (disabled ? "default" : "pointer")};
&:hover {
background-color: ${({ inverted }) =>
--
cgit v1.2.3-70-g09d2