Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Chat Tab #22

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"@parcel/compressor-brotli": "^2.8.3",
"@parcel/compressor-gzip": "^2.8.3",
"@parcel/config-default": "^2.8.3",
"@tailwindcss/typography": "^0.5.9",
"@types/chroma-js": "^2.4.0",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
Expand Down Expand Up @@ -48,12 +49,14 @@
"match-sorter": "^6.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-markdown": "^8.0.6",
"react-responsive": "^9.0.2",
"react-router-dom": "^6.8.1",
"react-scroll": "^1.8.9",
"react-select": "^5.7.0",
"react-tiny-popover": "^7.2.3",
"react-transition-group": "^4.4.5",
"remark-gfm": "^3.0.1",
"sort-by": "^1.2.0",
"sse.js": "^0.6.1",
"tailwind-merge": "^1.9.0",
Expand Down
14 changes: 13 additions & 1 deletion app/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from "react"
import {Playground, Compare, Settings} from "./pages"
import {Playground, Compare, Chat, Settings} from "./pages"
import {SSE} from "sse.js"
import {
EditorState,
Expand Down Expand Up @@ -600,6 +600,18 @@ function ProviderWithRoutes() {
}
/>

<Route
path="/chat"
element={
<APIContextWrapper>
{/* <PlaygroundContextWrapper key = "chat" page = "chat"> */}
<Chat/>
{/* <Toaster /> */}
{/* </PlaygroundContextWrapper> */}
</APIContextWrapper>
}
/>

<Route
path="/settings"
element={
Expand Down
7 changes: 7 additions & 0 deletions app/src/components/chat/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FC } from "react"

const Avatar: FC = () => {
return <div className="bg-red-500 rounded h-8 w-8"></div>
}

export default Avatar
31 changes: 31 additions & 0 deletions app/src/components/chat/message-composer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { FC, useState } from "react"

interface Props {
onSubmit: (content: string) => void
}

const MessageComposer: FC<Props> = ({ onSubmit }) => {
const [newMessage, setNewMessage] = useState("")

function handleSubmit(evt: React.FormEvent<HTMLFormElement>) {
evt.preventDefault()

if (!newMessage) return
onSubmit(newMessage)
setNewMessage("")
}

return (
<form onSubmit={handleSubmit}>
<input
className="block border rounded p-3 w-full shadow-md"
onChange={(evt) => setNewMessage(evt.target.value)}
placeholder="Send a message..."
type="text"
value={newMessage}
/>
</form>
)
}

export default MessageComposer
23 changes: 23 additions & 0 deletions app/src/components/chat/message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FC } from "react"
import ReactMarkdown from "react-markdown"
import remarkGfm from "remark-gfm"
import { IMessage } from "../../pages/chat"
import Avatar from "./avatar"

interface Props {
message: IMessage
}

const Message: FC<Props> = ({ message }) => {
return (
<div className="flex gap-4">
<Avatar />

<div className="prose">
<ReactMarkdown children={message.content} remarkPlugins={[remarkGfm]} />
</div>
</div>
)
}

export default Message
34 changes: 34 additions & 0 deletions app/src/components/chat/scroll-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { FC, ReactNode, useEffect, useRef, useState } from "react"

const ScrollContainer: FC<{ children: ReactNode }> = ({ children }) => {
const outerRef = useRef<HTMLDivElement>(null)
const innerRef = useRef<HTMLDivElement>(null)

const prevRender = useRef(false)

useEffect(() => {
const outerHeight = outerRef.current!.clientHeight
const innerHeight = innerRef.current!.clientHeight

outerRef.current!.scrollTo({
top: innerHeight - outerHeight,
left: 0,
behavior: prevRender.current ? "smooth" : "auto",
})

prevRender.current = true
}, [children])

return (
<div
className="relative h-full overflow-scroll overscroll-contain"
ref={outerRef}
>
<div className="relative" ref={innerRef}>
{children}
</div>
</div>
)
}

export default ScrollContainer
2 changes: 1 addition & 1 deletion app/src/components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react"
import { Link } from "react-router-dom"

export default function NavBar({ tab, children }: any) {
const menu = ["playground", "compare", "settings"].map((menuName, index) => (
const menu = ["playground", "compare", "chat", "settings"].map((menuName, index) => (
<div key = {menuName} className="align-middle mt-1 flex items-center">
<Link
to={`/${index > 0 ? menuName: ''}`}
Expand Down
186 changes: 186 additions & 0 deletions app/src/pages/chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import React from "react"
import Message from "../components/chat/message"
import MessageComposer from "../components/chat/message-composer"
import ScrollContainer from "../components/chat/scroll-container"
import NavBar from "../components/navbar"

export interface IMessage {
author: string
content: string
}

const initialMessages = [
{ author: "me", content: "How do I set up a Node.js TypeScript project?" },
{
author: "gpt-3.5",
content: `To set up a Node.js TypeScript project, you can follow these steps:

1. Install Node.js: If you don't have Node.js installed on your computer, you can download and install it from the official website (https://nodejs.org/en/).
2. Initialize a new Node.js project: Open a terminal and navigate to the directory where you want to create your project. Then, run the following command to initialize a new Node.js project:

\`\`\`
npm init -y
\`\`\`

This will create a new \`package.json\` file in your project directory.

3. Install TypeScript: Run the following command to install TypeScript as a development dependency:

\`\`\`
npm install --save-dev typescript
\`\`\`

4. Create a TypeScript configuration file: Create a new file named \`tsconfig.json\` in your project directory with the following contents:

\`\`\`
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"sourceMap": true,
"outDir": "dist"
},
"include": ["src/**/*"]
}
\`\`\`

This file specifies the TypeScript compiler options and tells it to compile all files in the src directory.`,
},
{
author: "gpt-3.5",
content: `To set up a Node.js TypeScript project, you can follow these steps:

1. Install Node.js: If you don't have Node.js installed on your computer, you can download and install it from the official website (https://nodejs.org/en/).
2. Initialize a new Node.js project: Open a terminal and navigate to the directory where you want to create your project. Then, run the following command to initialize a new Node.js project:

\`\`\`
npm init -y
\`\`\`

This will create a new \`package.json\` file in your project directory.

3. Install TypeScript: Run the following command to install TypeScript as a development dependency:

\`\`\`
npm install --save-dev typescript
\`\`\`

4. Create a TypeScript configuration file: Create a new file named \`tsconfig.json\` in your project directory with the following contents:

\`\`\`
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"sourceMap": true,
"outDir": "dist"
},
"include": ["src/**/*"]
}
\`\`\`

This file specifies the TypeScript compiler options and tells it to compile all files in the src directory.`,
},
{
author: "gpt-3.5",
content: `To set up a Node.js TypeScript project, you can follow these steps:

1. Install Node.js: If you don't have Node.js installed on your computer, you can download and install it from the official website (https://nodejs.org/en/).
2. Initialize a new Node.js project: Open a terminal and navigate to the directory where you want to create your project. Then, run the following command to initialize a new Node.js project:

\`\`\`
npm init -y
\`\`\`

This will create a new \`package.json\` file in your project directory.

3. Install TypeScript: Run the following command to install TypeScript as a development dependency:

\`\`\`
npm install --save-dev typescript
\`\`\`

4. Create a TypeScript configuration file: Create a new file named \`tsconfig.json\` in your project directory with the following contents:

\`\`\`
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"sourceMap": true,
"outDir": "dist"
},
"include": ["src/**/*"]
}
\`\`\`

This file specifies the TypeScript compiler options and tells it to compile all files in the src directory.`,
},
{
author: "gpt-3.5",
content: `To set up a Node.js TypeScript project, you can follow these steps:

1. Install Node.js: If you don't have Node.js installed on your computer, you can download and install it from the official website (https://nodejs.org/en/).
2. Initialize a new Node.js project: Open a terminal and navigate to the directory where you want to create your project. Then, run the following command to initialize a new Node.js project:

\`\`\`
npm init -y
\`\`\`

This will create a new \`package.json\` file in your project directory.

3. Install TypeScript: Run the following command to install TypeScript as a development dependency:

\`\`\`
npm install --save-dev typescript
\`\`\`

4. Create a TypeScript configuration file: Create a new file named \`tsconfig.json\` in your project directory with the following contents:

\`\`\`
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"sourceMap": true,
"outDir": "dist"
},
"include": ["src/**/*"]
}
\`\`\`

This file specifies the TypeScript compiler options and tells it to compile all files in the src directory.`,
},
] as IMessage[]

export default function Chat() {
const [messages, setMessages] = React.useState(initialMessages)

return (
<div className="flex flex-col h-full">
<NavBar tab="chat" />

<div className="flex-1 overflow-hidden">
<ScrollContainer>
{messages.map((message, index) => (
<div className="p-4" key={index}>
<div className="mx-auto max-w-3xl">
<Message message={message} />
</div>
</div>
))}
</ScrollContainer>
</div>

<div className="p-4">
<div className="mx-auto max-w-3xl">
<MessageComposer
onSubmit={(content) =>
setMessages([...messages, { author: "me", content }])
}
/>
</div>
</div>
</div>
)
}
3 changes: 2 additions & 1 deletion app/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Playground from "./playground"
import Compare from "./compare"
import Chat from "./chat"
import Settings from "./settings"

export { Playground, Compare, Settings };
export { Playground, Compare, Chat, Settings };
14 changes: 7 additions & 7 deletions app/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ module.exports = {
theme: {
extend: {
colors: {
'highlight-tokens': '#ff395ad1',
"highlight-tokens": "#ff395ad1",
},
screens: {
'3xl': '1792px',
'4xl': '2048px',
'5xl': '2748px',
'6xl': '3448px',
'8xl': '4000px'
"3xl": "1792px",
"4xl": "2048px",
"5xl": "2748px",
"6xl": "3448px",
"8xl": "4000px",
},
fontFamily: {
sans: ["var(--font-sans)", ...fontFamily.sans],
Expand All @@ -36,5 +36,5 @@ module.exports = {
},
},
},
plugins: [require("tailwindcss-animate")],
plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography")],
}