diff --git a/README.md b/README.md index eb9725b..343ad6d 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,23 @@ # screenshot-to-code -This is a simple app that converts a screenshot to HTML/Tailwind CSS. It uses GPT-4 Vision to generate the code, and DALL-E 3 to generate similar looking images. +This simple app converts a screenshot to HTML/Tailwind CSS. It uses GPT-4 Vision to generate the code and DALL-E 3 to generate similar-looking images. https://github.com/abi/screenshot-to-code/assets/23818/6cebadae-2fe3-4986-ac6a-8fb9db030045 -See [Examples](#examples) section below for more demos. +See the [Examples](#examples) section below for more demos. + +## 🚀 Try It Out! 🆕 [Try it here](https://picoapps.xyz/free-tools/screenshot-to-code) (bring your own OpenAI key - **your key must have access to GPT-4 Vision. See [FAQ](#faqs) section below for details**). Or see [Getting Started](#getting-started) below for local install instructions. -## Updates +## 🌟 Recent Updates +- Nov 19 - Support for dark/light code editor theme - thanks https://github.com/kachbit - Nov 16 - Added a setting to disable DALL-E image generation if you don't need that - Nov 16 - View code directly within the app -- Nov 15 - 🔥 You can now instruct the AI to update the code as you wish. Useful if the AI messed up some styles or missed a section. +- Nov 15 - 🔥 You can now instruct the AI to update the code as you wish. It is helpful if the AI messed up some styles or missed a section. -## Getting Started +## 🛠 Getting Started The app has a React/Vite frontend and a FastAPI backend. You will need an OpenAI API key with access to the GPT-4 Vision API. @@ -53,13 +56,13 @@ Application will be up and running at http://localhost:5173 Note that you can't develop the application with this setup as the file changes won't trigger a rebuild. -## FAQs +## 🙋‍♂️ FAQs - **I'm running into an error when setting up the backend. How can I fix it?** [Try this](https://github.com/abi/screenshot-to-code/issues/3#issuecomment-1814777959). If that still doesn't work, open an issue. - **How do I get an OpenAI API key that has the GPT4 Vision model available?** Create an OpenAI account. And then, you need to buy at least $1 worth of credit on the [Billing dashboard](https://platform.openai.com/account/billing/overview). - **How can I provide feedback?** For feedback, feature requests and bug reports, open an issue or ping me on [Twitter](https://twitter.com/_abi_). -## Examples +## 📚 Examples **NYTimes** @@ -75,6 +78,6 @@ https://github.com/abi/screenshot-to-code/assets/23818/503eb86a-356e-4dfc-926a-d https://github.com/abi/screenshot-to-code/assets/23818/3fec0f77-44e8-4fb3-a769-ac7410315e5d -## Hosted Version +## 🌍 Hosted Version 🆕 [Try it here](https://picoapps.xyz/free-tools/screenshot-to-code) (bring your own OpenAI key - **your key must have access to GPT-4 Vision. See [FAQ](#faqs) section for details**). Or see [Getting Started](#getting-started) for local install instructions. diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 654acf2..f579882 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -34,6 +34,7 @@ function App() { const [settings, setSettings] = useState({ openAiApiKey: null, isImageGenerationEnabled: true, + editorTheme: "cobalt" }); const downloadCode = () => { @@ -180,7 +181,6 @@ function App() { Original Screenshot -

Console @@ -231,7 +231,7 @@ function App() { - +

diff --git a/frontend/src/components/CodeMirror.tsx b/frontend/src/components/CodeMirror.tsx index 3ba1c51..21008bc 100644 --- a/frontend/src/components/CodeMirror.tsx +++ b/frontend/src/components/CodeMirror.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect } from "react"; import { EditorState } from "@codemirror/state"; import { EditorView, keymap, lineNumbers } from "@codemirror/view"; -import { cobalt } from "thememirror"; +import { espresso, cobalt } from "thememirror"; import { defaultKeymap, history, @@ -14,14 +14,18 @@ import { html } from "@codemirror/lang-html"; interface Props { code: string; + editorTheme: string; } -function CodeMirror({ code }: Props) { +function CodeMirror({ code, editorTheme }: Props) { const ref = useRef(null); const view = useRef(null); - // Initialize the editor when the component mounts useEffect(() => { + let selectedTheme = cobalt; + if (editorTheme === "espresso") { + selectedTheme = espresso; + } view.current = new EditorView({ state: EditorState.create({ doc: code, @@ -36,7 +40,7 @@ function CodeMirror({ code }: Props) { lineNumbers(), bracketMatching(), html(), - cobalt, + selectedTheme, EditorView.lineWrapping, ], }), @@ -49,9 +53,8 @@ function CodeMirror({ code }: Props) { view.current = null; } }; - }, []); + }, [code, editorTheme]); - // Update the contents of the editor when the code changes useEffect(() => { if (view.current && view.current.state.doc.toString() !== code) { view.current.dispatch({ @@ -60,6 +63,9 @@ function CodeMirror({ code }: Props) { } }, [code]); - return
; + return ( +
+ ); } + export default CodeMirror; diff --git a/frontend/src/components/SettingsDialog.tsx b/frontend/src/components/SettingsDialog.tsx index 512894f..33dd401 100644 --- a/frontend/src/components/SettingsDialog.tsx +++ b/frontend/src/components/SettingsDialog.tsx @@ -1,3 +1,4 @@ +import React from "react"; import { Dialog, DialogClose, @@ -12,6 +13,7 @@ import { Settings } from "../types"; import { Switch } from "./ui/switch"; import { Label } from "./ui/label"; import { Input } from "./ui/input"; +import { Select } from "./ui/select"; interface Props { settings: Settings; @@ -19,6 +21,13 @@ interface Props { } function SettingsDialog({ settings, setSettings }: Props) { + const handleThemeChange = (theme: string) => { + setSettings((s) => ({ + ...s, + editorTheme: theme, + })); + }; + return ( @@ -65,7 +74,23 @@ function SettingsDialog({ settings, setSettings }: Props) { })) } /> + +
+ +
+ Save diff --git a/frontend/src/components/ui/select.tsx b/frontend/src/components/ui/select.tsx new file mode 100644 index 0000000..6d4d943 --- /dev/null +++ b/frontend/src/components/ui/select.tsx @@ -0,0 +1,24 @@ +import * as React from "react"; +import { cn } from "@/lib/utils"; + +export interface SelectProps + extends React.SelectHTMLAttributes {} + +const Select = React.forwardRef( + ({ className, ...props }, ref) => { + return ( +