diff --git a/README.md b/README.md index e4739a4..92e26d2 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ See the [Examples](#-examples) section below for more demos. ## 🌟 Recent Updates +- Dec 11 - Start a new project from existing code (allows you to come back to an older project) - Dec 7 - 🔥 🔥 🔥 View a history of your edits, and branch off them - Nov 30 - Dark mode, output code in Ionic (thanks [@dialmedu](https://github.com/dialmedu)), set OpenAI base URL - Nov 28 - 🔥 🔥 🔥 Customize your stack: React or Bootstrap or TailwindCSS diff --git a/design-docs.md b/design-docs.md new file mode 100644 index 0000000..eb38119 --- /dev/null +++ b/design-docs.md @@ -0,0 +1,5 @@ +## Version History + +Version history is stored as a tree on the client-side. + + diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index d7db9db..4f3afb2 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from "react"; import ImageUpload from "./components/ImageUpload"; import CodePreview from "./components/CodePreview"; import Preview from "./components/Preview"; -import { CodeGenerationParams, generateCode } from "./generateCode"; +import { generateCode } from "./generateCode"; import Spinner from "./components/Spinner"; import classNames from "classnames"; import { @@ -18,7 +18,13 @@ import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "./components/ui/tabs"; import SettingsDialog from "./components/SettingsDialog"; -import { Settings, EditorTheme, AppState, GeneratedCodeConfig } from "./types"; +import { + AppState, + CodeGenerationParams, + EditorTheme, + GeneratedCodeConfig, + Settings, +} from "./types"; import { IS_RUNNING_ON_CLOUD } from "./config"; import { PicoBadge } from "./components/PicoBadge"; import { OnboardingNote } from "./components/OnboardingNote"; @@ -127,10 +133,21 @@ function App() { setIsImportedFromCode(false); }; - const stop = () => { + const cancelCodeGeneration = () => { wsRef.current?.close?.(USER_CLOSE_WEB_SOCKET_CODE); // make sure stop can correct the state even if the websocket is already closed - setAppState(AppState.CODE_READY); + cancelCodeGenerationAndReset(); + }; + + const cancelCodeGenerationAndReset = () => { + // When this is the first version, reset the entire app state + if (currentVersion === null) { + reset(); + } else { + // Otherwise, revert to the last version + setGeneratedCode(appHistory[currentVersion].code); + setAppState(AppState.CODE_READY); + } }; function doGenerateCode( @@ -187,6 +204,11 @@ function App() { } }, (line) => setExecutionConsole((prev) => [...prev, line]), + // On cancel + () => { + cancelCodeGenerationAndReset(); + }, + // On complete () => { setAppState(AppState.CODE_READY); } @@ -343,10 +365,10 @@ function App() {