For now, we only support React. To install our React library, run:
import React from 'react';
import {ChatProvider, Frame, Launcher, useChat} from '@booper/react';
const Chat = () => {
const scrollRef = React.useRef<HTMLDivElement | null>(null);
const [content, setMessageContent] = React.useState('');
const {messages, open, toggle, send, refresh} = useChat();
React.useEffect(() => {
scrollRef.current?.scrollIntoView();
}, [messages.length]);
const handleSendMessage = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setMessageContent('');
await send({content});
await refresh();
};
return (
<>
<Frame open={open}>
<div className="flex h-[70vh] w-96 flex-col overflow-hidden rounded-lg border bg-white text-gray-900 shadow-lg">
<div className="bg-gradient-to-r from-gray-900 via-gray-800 to-gray-700 px-4 py-4 text-gray-100 dark:border-gray-700">
<h1 className="mt-1 text-xl font-bold text-white">Hi there 👋</h1>
<p className="text-sm text-gray-200">
Let us know if you have any questions!
</p>
</div>
<ul className="flex-1 overflow-scroll border-b p-4">
{messages.map((message, index) => {
const isMe = message.source === 'chat'; // other sources: 'discord' and 'bot'
const next = messages[index + 1];
const isNextSame = next && next.source === message.source;
return (
<li
key={index}
className={`flex ${
isMe ? 'justify-end pl-8' : 'justify-start pr-8'
} ${isNextSame ? 'mb-1' : 'mb-3'}`}
>
<div
className={`rounded-md border px-3 py-2 text-sm ${
isMe ? 'bg-gray-800 text-white' : 'bg-gray-200'
}`}
>
{message.content}
</div>
</li>
);
})}
<div ref={scrollRef} />
</ul>
<form onSubmit={handleSendMessage}>
<input
className="w-full border-none bg-white p-4 text-sm outline-none"
placeholder="Type your message..."
value={content}
onChange={(e) => setMessageContent(e.target.value)}
/>
</form>
</div>
</Frame>
<Launcher open={open}>
<button
className="inline-flex h-10 w-10 items-center justify-center rounded-full bg-gray-800 text-sm font-medium text-gray-50 transition-colors hover:bg-gray-800/90 disabled:pointer-events-none disabled:opacity-70"
onClick={toggle}
>
{open ? (
<XIcon className="h-5 w-5 animate-in fade-in-0 duration-200" />
) : (
<ChatIcon className="h-5 w-5 animate-in fade-in-0 duration-200" />
)}
</button>
</Launcher>
</>
);
};
export default function App() {
return (
<ChatProvider appId={YOUR_APP_ID}>
<Chat />
</ChatProvider>
);
};