From 05f3a1f35f1d0f85df15ac78f2f285d54ab45118 Mon Sep 17 00:00:00 2001 From: Ty Dunn Date: Mon, 10 Jul 2023 15:25:29 -0700 Subject: adding onboarding --- extension/react-app/src/components/Onboarding.tsx | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 extension/react-app/src/components/Onboarding.tsx (limited to 'extension/react-app/src/components') diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx new file mode 100644 index 00000000..373f7bea --- /dev/null +++ b/extension/react-app/src/components/Onboarding.tsx @@ -0,0 +1,51 @@ +import { useSelector } from "react-redux"; +import { RootStore } from "../redux/store"; +import React, { useState } from 'react'; + + +const Onboarding = () => { + const [counter, setCounter] = useState(0); + + const handleClick = () => { + setCounter(counter + 1); + } + + const vscMediaUrl = useSelector( + (state: RootStore) => state.config.vscMediaUrl + ); + + return ( +
+ {counter === 0 && ( +
+

Welcome to Continue!

+ Intro +
+ )} + {counter === 1 && ( +
+

Answer coding questions

+ Explain +

Ask Continue about a part of your code to get another perspective

+
+ )} + {counter === 2 && ( +
+

Edit in natural language

+ Edit +

Highlight a section of code and instruct Continue to refactor it

+
+ )} + {counter === 3 && ( +
+

Generate files from scratch

+ Generate +

Let Continue build the scaffolding of Python scripts, React components, and more

+
+ )} +

Click to learn how to use Continue...

+
+ ); +} + +export default Onboarding; -- cgit v1.2.3-70-g09d2 From 78168d47e3b2642bbd0eb6b4d072e9ca8c70ecba Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Mon, 10 Jul 2023 17:31:38 -0700 Subject: sprucing up onboarding --- extension/react-app/src/components/Onboarding.tsx | 146 ++++++++++++++++------ 1 file changed, 105 insertions(+), 41 deletions(-) (limited to 'extension/react-app/src/components') diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx index 373f7bea..0e188e7a 100644 --- a/extension/react-app/src/components/Onboarding.tsx +++ b/extension/react-app/src/components/Onboarding.tsx @@ -1,51 +1,115 @@ import { useSelector } from "react-redux"; import { RootStore } from "../redux/store"; -import React, { useState } from 'react'; +import React, { useState, useEffect } from "react"; +import styled from "styled-components"; +import { ArrowLeft, ArrowRight } from "@styled-icons/heroicons-outline"; +import { defaultBorderRadius } from "."; +const StyledDiv = styled.div` + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: #1e1e1e; + z-index: 200; +`; + +const StyledSpan = styled.span` + padding: 8px; + border-radius: ${defaultBorderRadius}; + &:hover { + background-color: #ffffff33; + } +`; const Onboarding = () => { - const [counter, setCounter] = useState(0); + const [counter, setCounter] = useState(4); + const gifs = ["intro", "explain", "edit", "generate"]; + const topMessages = [ + "Welcome to Continue!", + "Answer coding questions", + "Edit in natural language", + "Generate files from scratch", + ]; + const bottomMessages = [ + "", + "Ask Continue about a part of your code to get another perspective", + "Highlight a section of code and instruct Continue to refactor it", + "Let Continue build the scaffolding of Python scripts, React components, and more", + ]; - const handleClick = () => { - setCounter(counter + 1); - } + const vscMediaUrl = useSelector( + (state: RootStore) => state.config.vscMediaUrl + ); - const vscMediaUrl = useSelector( - (state: RootStore) => state.config.vscMediaUrl - ); + useEffect(() => { + const hasVisited = localStorage.getItem("hasVisited"); + if (hasVisited) { + setCounter(4); + } else { + setCounter(0); + localStorage.setItem("hasVisited", "true"); + } + }, []); - return ( -
- {counter === 0 && ( -
-

Welcome to Continue!

- Intro -
- )} - {counter === 1 && ( -
-

Answer coding questions

- Explain -

Ask Continue about a part of your code to get another perspective

-
- )} - {counter === 2 && ( -
-

Edit in natural language

- Edit -

Highlight a section of code and instruct Continue to refactor it

-
- )} - {counter === 3 && ( -
-

Generate files from scratch

- Generate -

Let Continue build the scaffolding of Python scripts, React components, and more

-
- )} -

Click to learn how to use Continue...

-
- ); -} + return ( + + ); +}; export default Onboarding; -- cgit v1.2.3-70-g09d2 From 194968d72aea838c64058262003e664ee4282626 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Mon, 10 Jul 2023 20:08:04 -0700 Subject: gifs in outside media folder --- extension/package-lock.json | 4 ++-- extension/package.json | 2 +- extension/react-app/public/edit.gif | Bin 41667733 -> 0 bytes extension/react-app/public/explain.gif | Bin 56475028 -> 0 bytes extension/react-app/public/generate.gif | Bin 32532380 -> 0 bytes extension/react-app/public/intro.gif | Bin 3976676 -> 0 bytes extension/react-app/src/components/Onboarding.tsx | 2 +- media/edit.gif | Bin 0 -> 41667733 bytes media/explain.gif | Bin 0 -> 56475028 bytes media/generate.gif | Bin 0 -> 32532380 bytes media/intro.gif | Bin 0 -> 3976676 bytes 11 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 extension/react-app/public/edit.gif delete mode 100644 extension/react-app/public/explain.gif delete mode 100644 extension/react-app/public/generate.gif delete mode 100644 extension/react-app/public/intro.gif create mode 100644 media/edit.gif create mode 100644 media/explain.gif create mode 100644 media/generate.gif create mode 100644 media/intro.gif (limited to 'extension/react-app/src/components') diff --git a/extension/package-lock.json b/extension/package-lock.json index 5733c2dd..52b2e7b9 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.143", + "version": "0.0.146", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.143", + "version": "0.0.146", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 0477a450..393c5d70 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.143", + "version": "0.0.146", "publisher": "Continue", "engines": { "vscode": "^1.67.0" diff --git a/extension/react-app/public/edit.gif b/extension/react-app/public/edit.gif deleted file mode 100644 index 6780cdf7..00000000 Binary files a/extension/react-app/public/edit.gif and /dev/null differ diff --git a/extension/react-app/public/explain.gif b/extension/react-app/public/explain.gif deleted file mode 100644 index e74803dc..00000000 Binary files a/extension/react-app/public/explain.gif and /dev/null differ diff --git a/extension/react-app/public/generate.gif b/extension/react-app/public/generate.gif deleted file mode 100644 index 5c1d112b..00000000 Binary files a/extension/react-app/public/generate.gif and /dev/null differ diff --git a/extension/react-app/public/intro.gif b/extension/react-app/public/intro.gif deleted file mode 100644 index f872dc91..00000000 Binary files a/extension/react-app/public/intro.gif and /dev/null differ diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx index 0e188e7a..1cbe61ec 100644 --- a/extension/react-app/src/components/Onboarding.tsx +++ b/extension/react-app/src/components/Onboarding.tsx @@ -76,7 +76,7 @@ const Onboarding = () => {

{topMessages[counter]}

{topMessages[counter]}
diff --git a/media/edit.gif b/media/edit.gif new file mode 100644 index 00000000..6780cdf7 Binary files /dev/null and b/media/edit.gif differ diff --git a/media/explain.gif b/media/explain.gif new file mode 100644 index 00000000..e74803dc Binary files /dev/null and b/media/explain.gif differ diff --git a/media/generate.gif b/media/generate.gif new file mode 100644 index 00000000..5c1d112b Binary files /dev/null and b/media/generate.gif differ diff --git a/media/intro.gif b/media/intro.gif new file mode 100644 index 00000000..f872dc91 Binary files /dev/null and b/media/intro.gif differ -- cgit v1.2.3-70-g09d2 From 05b88d942053eb1edf05490c37fc5e9150bc98c4 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Mon, 10 Jul 2023 23:07:23 -0700 Subject: fixed gif link --- extension/react-app/src/components/Onboarding.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'extension/react-app/src/components') diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx index 1cbe61ec..061faba5 100644 --- a/extension/react-app/src/components/Onboarding.tsx +++ b/extension/react-app/src/components/Onboarding.tsx @@ -76,7 +76,7 @@ const Onboarding = () => {

{topMessages[counter]}

{topMessages[counter]}
-- cgit v1.2.3-70-g09d2 From 721735d65a2b6f3811514396891c90b950686323 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 11 Jul 2023 11:31:41 -0700 Subject: explain insert at cursor, better diff streaming --- continuedev/src/continuedev/steps/core/core.py | 44 ++++++++++++++++++++++--- extension/react-app/src/components/ComboBox.tsx | 32 +++++++++++++++--- extension/src/diffs.ts | 7 +++- 3 files changed, 72 insertions(+), 11 deletions(-) (limited to 'extension/react-app/src/components') diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index b0d9d719..d4d067ba 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -265,6 +265,23 @@ class DefaultModelEditCodeStep(Step): return file_prefix, rif.contents, file_suffix, model_to_use, max_tokens def compile_prompt(self, file_prefix: str, contents: str, file_suffix: str, sdk: ContinueSDK) -> str: + if contents.strip() == "": + # Seperate prompt for insertion at the cursor, the other tends to cause it to repeat whole file + prompt = dedent(f"""\ + +{file_prefix} + + + +{file_suffix} + + +{self.user_input} + + +Please output the code to be inserted at the cursor in order to fulfill the user_request. Do NOT preface your answer or write anything other than code. You should not write any tags, just the code. Make sure to correctly indent the code:""") + return prompt + prompt = self._prompt if file_prefix.strip() != "": prompt += dedent(f""" @@ -306,15 +323,32 @@ class DefaultModelEditCodeStep(Step): prompt = self.compile_prompt(file_prefix, contents, file_suffix, sdk) full_file_contents_lines = full_file_contents.split("\n") - async def sendDiffUpdate(lines: List[str], sdk: ContinueSDK): - nonlocal full_file_contents_lines, rif + lines_to_display = [] + + async def sendDiffUpdate(lines: List[str], sdk: ContinueSDK, final: bool = False): + nonlocal full_file_contents_lines, rif, lines_to_display completion = "\n".join(lines) full_prefix_lines = full_file_contents_lines[:rif.range.start.line] full_suffix_lines = full_file_contents_lines[rif.range.end.line:] + + # Don't do this at the very end, just show the inserted code + if final: + lines_to_display = [] + # Only recalculate at every new-line, because this is sort of expensive + elif completion.endswith("\n"): + contents_lines = rif.contents.split("\n") + rewritten_lines = 0 + for line in lines: + for i in range(rewritten_lines, len(contents_lines)): + if difflib.SequenceMatcher(None, line, contents_lines[i]).ratio() > 0.7 and contents_lines[i].strip() != "": + rewritten_lines = i + 1 + break + lines_to_display = contents_lines[rewritten_lines:] + new_file_contents = "\n".join( - full_prefix_lines) + "\n" + completion + "\n" + "\n".join(full_suffix_lines) + full_prefix_lines) + "\n" + completion + "\n" + "\n".join(lines_to_display) + "\n" + "\n".join(full_suffix_lines) step_index = sdk.history.current_index @@ -495,7 +529,7 @@ class DefaultModelEditCodeStep(Step): completion_lines_covered += 1 current_line_in_file += 1 - await sendDiffUpdate(lines + [common_whitespace + unfinished_line], sdk) + await sendDiffUpdate(lines + [common_whitespace if unfinished_line.startswith("<") else (common_whitespace + unfinished_line)], sdk) # Add the unfinished line if unfinished_line != "" and not self.line_to_be_ignored(unfinished_line, completion_lines_covered == 0) and not self.is_end_line(unfinished_line): @@ -505,7 +539,7 @@ class DefaultModelEditCodeStep(Step): completion_lines_covered += 1 current_line_in_file += 1 - await sendDiffUpdate(lines, sdk) + await sendDiffUpdate(lines, sdk, final=True) if False: # If the current block isn't empty, add that suggestion diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 801c3a03..585a0584 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -180,6 +180,26 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { useImperativeHandle(ref, () => downshiftProps, [downshiftProps]); + const [metaKeyPressed, setMetaKeyPressed] = useState(false); + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === "Meta") { + setMetaKeyPressed(true); + } + }; + const handleKeyUp = (e: KeyboardEvent) => { + if (e.key === "Meta") { + setMetaKeyPressed(false); + } + }; + window.addEventListener("keydown", handleKeyDown); + window.addEventListener("keyup", handleKeyUp); + return () => { + window.removeEventListener("keydown", handleKeyDown); + window.removeEventListener("keyup", handleKeyUp); + }; + }); + useEffect(() => { if (!inputRef.current) { return; @@ -272,7 +292,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { - {/* - Highlight code to include as context. Currently open file included by - default. {highlightedCodeSections.length === 0 && ""} - */} + {highlightedCodeSections.length === 0 && + (downshiftProps.inputValue?.startsWith("/edit") || metaKeyPressed) && ( +
+ Inserting at cursor +
+ )} { setHoveringContextDropdown(true); diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts index 1dc292e1..3ea6b4f8 100644 --- a/extension/src/diffs.ts +++ b/extension/src/diffs.ts @@ -164,7 +164,12 @@ class DiffManager { // Stop the step at step_index in case it is still streaming ideProtocolClient.deleteAtIndex(diffInfo.step_index); - this.cleanUpDiff(diffInfo); + vscode.workspace.textDocuments + .find((doc) => doc.uri.fsPath === newFilepath) + ?.save() + .then(() => { + this.cleanUpDiff(diffInfo); + }); } } -- cgit v1.2.3-70-g09d2 From 3ca5c52e83f27bc1cda1b3f696dc86296ada2370 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 11 Jul 2023 14:13:14 -0700 Subject: little ui stuff --- extension/react-app/src/components/ComboBox.tsx | 3 ++- extension/react-app/src/tabs/gui.tsx | 11 +++-------- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'extension/react-app/src/components') diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 585a0584..ac994b0a 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -378,7 +378,8 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { {highlightedCodeSections.length === 0 && - (downshiftProps.inputValue?.startsWith("/edit") || metaKeyPressed) && ( + (downshiftProps.inputValue?.startsWith("/edit") || + (metaKeyPressed && downshiftProps.inputValue?.length > 0)) && (
Inserting at cursor
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx index 0e60e05c..619b91e1 100644 --- a/extension/react-app/src/tabs/gui.tsx +++ b/extension/react-app/src/tabs/gui.tsx @@ -170,6 +170,7 @@ function GUI(props: GUIProps) { const waitingForSteps = state.active && state.history.current_index < state.history.timeline.length && + state.history.timeline[state.history.current_index] && state.history.timeline[ state.history.current_index ].step.description?.trim() === ""; @@ -236,14 +237,14 @@ function GUI(props: GUIProps) { history.current_index < history.timeline.length ) { if ( - history.timeline[history.current_index].step.name === + history.timeline[history.current_index]?.step.name === "Waiting for user input" ) { if (input.trim() === "") return; onStepUserInput(input, history!.current_index); return; } else if ( - history.timeline[history.current_index].step.name === + history.timeline[history.current_index]?.step.name === "Waiting for user confirmation" ) { onStepUserInput("ok", history!.current_index); @@ -350,12 +351,6 @@ function GUI(props: GUIProps) { { onMainTextInput(e); -- cgit v1.2.3-70-g09d2 From 67d6a3f0ea00e55aea47b4eeff4cdb0d8321ce2f Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 11 Jul 2023 18:25:48 -0700 Subject: onboarding fix --- extension/react-app/src/components/Onboarding.tsx | 27 +++++++++-------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'extension/react-app/src/components') diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx index 061faba5..1b37acc4 100644 --- a/extension/react-app/src/components/Onboarding.tsx +++ b/extension/react-app/src/components/Onboarding.tsx @@ -87,25 +87,20 @@ const Onboarding = () => { paddingRight: "50px", paddingBottom: "50px", textAlign: "center", + cursor: "pointer", }} > - + Previous + + + setCounter((prev) => prev + 1)}> + Click to {counter === 3 || "learn how to"} use Continue{" "} + +

-- cgit v1.2.3-70-g09d2 From e424831f6103c0f08d021085de106d1f6c37d327 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 12 Jul 2023 10:03:11 -0700 Subject: better onboarding --- extension/package-lock.json | 4 +- extension/package.json | 2 +- extension/react-app/src/components/Onboarding.tsx | 51 ++++++++++++++++++----- extension/src/activation/activate.ts | 2 +- 4 files changed, 45 insertions(+), 14 deletions(-) (limited to 'extension/react-app/src/components') diff --git a/extension/package-lock.json b/extension/package-lock.json index d310643b..5d1cf395 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.153", + "version": "0.0.154", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.153", + "version": "0.0.154", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 61eee205..ab23b0b0 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.153", + "version": "0.0.154", "publisher": "Continue", "engines": { "vscode": "^1.67.0" diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx index 1b37acc4..776ad460 100644 --- a/extension/react-app/src/components/Onboarding.tsx +++ b/extension/react-app/src/components/Onboarding.tsx @@ -4,6 +4,7 @@ import React, { useState, useEffect } from "react"; import styled from "styled-components"; import { ArrowLeft, ArrowRight } from "@styled-icons/heroicons-outline"; import { defaultBorderRadius } from "."; +import Loader from "./Loader"; const StyledDiv = styled.div` position: absolute; @@ -39,13 +40,9 @@ const Onboarding = () => { "Let Continue build the scaffolding of Python scripts, React components, and more", ]; - const vscMediaUrl = useSelector( - (state: RootStore) => state.config.vscMediaUrl - ); - useEffect(() => { const hasVisited = localStorage.getItem("hasVisited"); - if (hasVisited) { + if (hasVisited && false) { setCounter(4); } else { setCounter(0); @@ -53,6 +50,12 @@ const Onboarding = () => { } }, []); + const [loading, setLoading] = useState(true); + + useEffect(() => { + setLoading(true); + }, [counter]); + return (