├── .eslintrc.json ├── .github └── image.png ├── .gitignore ├── LICENSE ├── README.md ├── components ├── Button.tsx ├── ChannelTop.tsx ├── ChatBar.tsx ├── Image.tsx ├── Message.tsx ├── MessageList.tsx ├── PromptBook.tsx ├── PromptEngine.tsx └── Settings.tsx ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── _app.tsx └── index.tsx ├── postcss.config.js ├── public ├── favicon.ico └── vercel.svg ├── styles └── globals.css ├── tailwind.config.js └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.github/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KAJdev/diffusion-chat/cc213f1b760f216d5c5a979de357e3acb51bdc36/.github/image.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /api 6 | /.pnp 7 | .pnp.js 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | .pnpm-debug.log* 28 | 29 | # local env files 30 | .env*.local 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | 39 | .env 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Ezekiel Wotring 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Diffusion Chat 3 | The future of human-AI interaction is conversation. Inference is iterative. Diffusion Chat allows you to speak directly to Stable Diffusion. Built in nextjs (edge runtime), tailwindcss, zustand. Communicating with the Stability AI REST API. 4 | 5 | Live version of the site at https://diffusion.chat 6 | 7 |  8 | 9 | ## Contributing 10 | Just make a PR and try to follow the functional paradigm. All skill levels welcome. Let's build AI interactions together :). 11 | -------------------------------------------------------------------------------- /components/Button.tsx: -------------------------------------------------------------------------------- 1 | import { Message } from "./Message"; 2 | import { PromptBook } from "./PromptBook"; 3 | 4 | function saveImage(image: string, name: string) { 5 | // download image from external URL 6 | fetch(image) 7 | .then((res) => res.blob()) 8 | .then((blob) => { 9 | // create blob link to download 10 | const url = window.URL.createObjectURL(new Blob([blob])); 11 | const link = document.createElement("a"); 12 | link.setAttribute("download", `${name}.png`); 13 | link.setAttribute("href", url); 14 | document.body.appendChild(link); 15 | link.click(); 16 | link.remove(); 17 | }); 18 | } 19 | 20 | export function Button({ 21 | btn, 22 | message, 23 | selectedImage, 24 | }: { 25 | btn: Button; 26 | message: Message; 27 | selectedImage: number; 28 | }) { 29 | const addPrompt = PromptBook.use((state) => state.addPrompt); 30 | 31 | return ( 32 | 60 | ); 61 | } 62 | 63 | export type Button = { 64 | text: string; 65 | id: string; 66 | }; 67 | -------------------------------------------------------------------------------- /components/ChannelTop.tsx: -------------------------------------------------------------------------------- 1 | import { MessageCircle } from "lucide-react"; 2 | 3 | export function ChannelTop() { 4 | return ( 5 | <> 6 |
64 | {new Date(message.timestamp).toLocaleTimeString()} 65 |
66 | )} 67 | {message.modifiers && ( 68 |{message.prompt}
73 | )} 74 | {message.images && message.settings && message.images.length > 0 && ( 75 |{message.error}
} 92 | {message.loading && message.images && message.images.length === 0 && ( 93 |No prompts saved
94 | )} 95 |88 | {settings.width}x{settings.height} 89 |
90 |{settings.count}
112 |{settings.steps}
133 |{settings.scale}
154 |183 | Adds modifiers and negative prompts to your generations 184 |
185 |