Skip to content
46 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Chat and workspace agents: channels, DMs and named agents you talk to1import { Hash, MessagesSquare, PlugZap } from "lucide-react";
2import type { ReactNode } from "react";
3import { useParams } from "react-router";
4
5import { CreateChannelButton, NewMessageButton } from "./actions";
6
7/** A calm full-height panel for a conversation that cannot be shown. */
8function Panel({ icon, title, children }: { icon: ReactNode; title: string; children: ReactNode }) {
9 return (
10 <div className="flex h-[calc(100dvh-3.5rem)] items-center justify-center px-6 lg:h-dvh">
11 <div className="max-w-sm text-center">
12 <div className="mx-auto flex size-12 items-center justify-center rounded-xl border border-line bg-surface text-muted">{icon}</div>
13 <h1 className="mt-4 text-base font-semibold">{title}</h1>
14 <div className="mt-1.5 text-sm text-muted">{children}</div>
15 </div>
16 </div>
17 );
18}
19
20/** Chat did not answer: it may be deploying a moment after the site. */
21export function ChatUnavailable({ title = "Chat" }: { title?: string }) {
22 return (
23 <Panel icon={<PlugZap size={20} />} title={`${title} isn't reachable right now`}>
24 Chat didn't answer. It's usually back within a minute; reload to try again. Nothing you sent is lost.
25 </Panel>
26 );
27}
28
29/** A workspace with no conversations yet. */
30export function NoChannels() {
31 const { owner = "" } = useParams();
32 return (
33 <Panel icon={<MessagesSquare size={20} />} title="Start the first conversation">
34 <p>Channels keep a topic in one place. Direct messages are for one person, a few, or an agent.</p>
35 <div className="mt-5 flex justify-center gap-2">
36 <CreateChannelButton slug={owner.toLowerCase()} variant="button" />
37 <NewMessageButton slug={owner.toLowerCase()} variant="button" />
38 </div>
39 </Panel>
40 );
41}
42
43/** A channel's name with its mark, as the header and the sidebar show it. */
44export function ChannelGlyph({ className }: { className?: string }) {
45 return <Hash size={16} className={className} />;
46}