From ae058c6bac7ea37108e2894e419a22dfb95fd3ff Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Sat, 12 Aug 2023 12:13:49 -0700 Subject: feat: :lipstick: UI Improvements! --- continuedev/src/continuedev/core/autopilot.py | 1 - .../src/continuedev/server/session_manager.py | 2 +- extension/react-app/src/components/Layout.tsx | 86 ++++----------- .../react-app/src/components/StepContainer.tsx | 122 ++++++++++----------- .../src/components/StyledMarkdownPreview.tsx | 2 +- .../src/components/UserInputContainer.tsx | 54 ++++++--- 6 files changed, 117 insertions(+), 150 deletions(-) diff --git a/continuedev/src/continuedev/core/autopilot.py b/continuedev/src/continuedev/core/autopilot.py index 9100c34e..2c58c6f4 100644 --- a/continuedev/src/continuedev/core/autopilot.py +++ b/continuedev/src/continuedev/core/autopilot.py @@ -85,7 +85,6 @@ class Autopilot(ContinueBaseModel): if full_state is not None: self.history = full_state.history - self.context_manager.context_providers["code"].adding_highlighted_code = full_state.adding_highlighted_code self.session_info = full_state.session_info self.started = True diff --git a/continuedev/src/continuedev/server/session_manager.py b/continuedev/src/continuedev/server/session_manager.py index cde0344e..88ac13f6 100644 --- a/continuedev/src/continuedev/server/session_manager.py +++ b/continuedev/src/continuedev/server/session_manager.py @@ -78,7 +78,7 @@ class SessionManager: try: await autopilot.start(full_state=full_state) except Exception as e: - await self.on_error(e) + await ide.on_error(e) def on_error(e: Exception) -> Coroutine: err_msg = '\n'.join(traceback.format_exception(e)) diff --git a/extension/react-app/src/components/Layout.tsx b/extension/react-app/src/components/Layout.tsx index a3b1946a..0721585d 100644 --- a/extension/react-app/src/components/Layout.tsx +++ b/extension/react-app/src/components/Layout.tsx @@ -3,15 +3,13 @@ import { defaultBorderRadius, secondaryDark, vscForeground } from "."; import { Outlet } from "react-router-dom"; import Onboarding from "./Onboarding"; import TextDialog from "./TextDialog"; -import { useContext } from "react"; +import { useContext, useEffect } from "react"; import { GUIClientContext } from "../App"; import { useDispatch, useSelector } from "react-redux"; import { RootStore } from "../redux/store"; import { setBottomMessage, setBottomMessageCloseTimeout, - setDialogEntryOn, - setDialogMessage, setShowDialog, } from "../redux/slices/uiStateSlice"; import { @@ -57,8 +55,6 @@ const Footer = styled.footer` justify-content: right; padding: 8px; align-items: center; - margin-top: 8px; - border-top: 0.1px solid gray; `; // #endregion @@ -78,9 +74,6 @@ const Layout = () => { ); // #region Selectors - const vscMediaUrl = useSelector( - (state: RootStore) => state.config.vscMediaUrl - ); const bottomMessage = useSelector( (state: RootStore) => state.uiState.bottomMessage @@ -91,6 +84,20 @@ const Layout = () => { // #endregion + useEffect(() => { + const handleKeyDown = (event: any) => { + if (event.metaKey && event.key === "n" && event.altKey) { + client?.loadSession(undefined); + } + }; + + window.addEventListener("keydown", handleKeyDown); + + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, [client]); + return (
{ {bottomMessage}
- {vscMediaUrl && ( - - - - )} - { - // Show the dialog - dispatch( - setDialogMessage(`Continue uses GPT-4 by default, but works with any model. If you'd like to keep your code completely private, there are few options: - - Run a local model with ggml: [5 minute quickstart](https://github.com/continuedev/ggml-server-example) - - Use Azure OpenAI service, which is GDPR and HIPAA compliant: [Tutorial](https://continue.dev/docs/customization#azure-openai-service) - - If you already have an LLM deployed on your own infrastructure, or would like to do so, please contact us at hi@continue.dev. - `) - ); - dispatch(setDialogEntryOn(false)); - dispatch(setShowDialog(true)); - }} - text={"Use Private Model"} - > -
- 🔒 -
-
{ client?.loadSession(undefined); }} - text="New Session" + text="New Session (⌥⌘N)" > @@ -195,21 +162,14 @@ const Layout = () => { - { - // Set dialog open - dispatch( - setDialogMessage( - "Having trouble using Continue? Want a new feature? Let us know! This box is anonymous, but we will promptly address your feedback." - ) - ); - dispatch(setDialogEntryOn(true)); - dispatch(setShowDialog(true)); - }} - text="Feedback" + - - + + + +
diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index fe81e9e1..ce7d9a58 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -1,12 +1,6 @@ import { useContext, useEffect, useRef, useState } from "react"; import styled, { keyframes } from "styled-components"; -import { - defaultBorderRadius, - secondaryDark, - vscBackground, - vscBackgroundTransparent, - vscForeground, -} from "."; +import { secondaryDark, vscBackground } from "."; import { ChevronDownIcon, ChevronRightIcon, @@ -48,18 +42,10 @@ const MainDiv = styled.div<{ margin-right: 0px; `; -const StepContainerDiv = styled.div<{ open: boolean }>` - /* background-color: ${(props) => - props.open ? vscBackground : secondaryDark}; */ - /* border-radius: ${defaultBorderRadius}; */ - /* padding: 8px; */ -`; - const HeaderDiv = styled.div<{ error: boolean; loading: boolean }>` background-color: ${(props) => (props.error ? "#522" : vscBackground)}; display: grid; grid-template-columns: 1fr auto auto; - grid-gap: 8px; align-items: center; padding-right: 8px; `; @@ -73,7 +59,8 @@ const LeftHeaderSubDiv = styled.div` `; const ContentDiv = styled.div<{ isUserInput: boolean }>` - padding: 8px; + padding-left: 4px; + padding-right: 2px; background-color: ${(props) => props.isUserInput ? secondaryDark : vscBackground}; font-size: 13px; @@ -151,9 +138,9 @@ function StepContainer(props: StepContainerProps) { }} hidden={props.historyNode.step.hide as any} > - +
*/} - - <> - {(props.historyNode.logs as any)?.length > 0 && ( + {(isHovered || (props.historyNode.active as boolean)) && ( +
+ {(props.historyNode.logs as any)?.length > 0 && ( + { + e.stopPropagation(); + client?.showLogsAtIndex(props.index); + }} + > + + + )} { e.stopPropagation(); - client?.showLogsAtIndex(props.index); + props.onDelete(); }} + text={ + props.historyNode.active + ? `Stop (${getMetaKeyLabel()}⌫)` + : "Delete" + } > - + {props.historyNode.active ? ( + + ) : ( + + )} - )} - { - e.stopPropagation(); - props.onDelete(); - }} - text={ - props.historyNode.active - ? `Stop (${getMetaKeyLabel()}⌫)` - : "Delete" - } - > - {props.historyNode.active ? ( - + {props.historyNode.observation?.error ? ( + { + e.stopPropagation(); + props.onRetry(); + }} + > + + ) : ( - + <> )} - - {props.historyNode.observation?.error ? ( - { - e.stopPropagation(); - props.onRetry(); - }} - > - - - ) : ( - <> - )} - +
+ )}
- +
); } diff --git a/extension/react-app/src/components/StyledMarkdownPreview.tsx b/extension/react-app/src/components/StyledMarkdownPreview.tsx index b1079c96..5957f8dd 100644 --- a/extension/react-app/src/components/StyledMarkdownPreview.tsx +++ b/extension/react-app/src/components/StyledMarkdownPreview.tsx @@ -11,7 +11,6 @@ const StyledMarkdownPreview = styled(MarkdownPreview)<{ light?: boolean }>` pre { background-color: ${(props) => props.light ? vscBackground : secondaryDark}; - padding: 1px; border-radius: ${defaultBorderRadius}; border: 0.5px solid white; } @@ -27,6 +26,7 @@ const StyledMarkdownPreview = styled(MarkdownPreview)<{ light?: boolean }>` background-color: ${(props) => props.light ? vscBackground : secondaryDark}; color: ${vscForeground}; + padding: 10px; } background-color: ${(props) => (props.light ? "transparent" : vscBackground)}; diff --git a/extension/react-app/src/components/UserInputContainer.tsx b/extension/react-app/src/components/UserInputContainer.tsx index 7e964ad9..90cd549b 100644 --- a/extension/react-app/src/components/UserInputContainer.tsx +++ b/extension/react-app/src/components/UserInputContainer.tsx @@ -1,7 +1,7 @@ -import React from "react"; +import React, { useState } from "react"; import ReactMarkdown from "react-markdown"; import styled from "styled-components"; -import { secondaryDark, vscBackground } from "."; +import { defaultBorderRadius, secondaryDark, vscBackground } from "."; import HeaderButtonWithText from "./HeaderButtonWithText"; import { XMarkIcon } from "@heroicons/react/24/outline"; import { HistoryNode } from "../../../schema/HistoryNode"; @@ -21,35 +21,55 @@ const StyledDiv = styled.div` align-items: center; border-bottom: 1px solid ${vscBackground}; padding: 8px; - padding-top: 4px; - padding-bottom: 4px; + padding-top: 0px; + padding-bottom: 0px; `; const DeleteButtonDiv = styled.div` position: absolute; top: 8px; - right: 16px; + right: 8px; +`; + +const StyledPre = styled.pre` + margin-right: 22px; + margin-left: 8px; + white-space: pre-wrap; + word-wrap: break-word; + font-family: "Lexend", sans-serif; + font-size: 13px; `; const UserInputContainer = (props: UserInputContainerProps) => { + const [isHovered, setIsHovered] = useState(false); return ( - - { + setIsHovered(true); + }} + onMouseLeave={() => { + setIsHovered(false); + }} + > + {/* + /> */} + {props.children} {/* */} - { - props.onDelete(); - e.stopPropagation(); - }} - text="Delete" - > - - + {isHovered && ( + { + props.onDelete(); + e.stopPropagation(); + }} + text="Delete" + > + + + )} ); -- cgit v1.2.3-70-g09d2