Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
75 linesCodeBlameRaw
1import { AgentAvatar } from "../agent-avatar";
2import { WithPresence } from "../presence";
3
4import { cn } from "../../lib/cn";
5import { Avatar } from "../ui/avatar";
6import { Hint } from "../ui/hint";
7
8/**
9 * A member's face: a person's avatar, or, on an old message from an agent
10 * that no longer exists (or one from g1t), a plain tile with the agent
11 * marker (components/ui/avatar.tsx). With `presence`, a person's carries
12 * their dot (active, away, notifications paused; components/presence.tsx),
13 * cut out of `ring`, the colour behind it, which also rings the marker.
14 */
15export function MemberAvatar({
16 member,
17 size = 20,
18 presence = false,
19 ring,
20}: {
21 member: { kind: "user" | "agent" | "system"; id?: string; name: string; avatar: string | null };
22 size?: number;
23 presence?: boolean;
24 ring?: string;
25}) {
26 // @g1t: the g1t mark, with the agent marker.
27 if (member.kind === "system") return <Avatar name="g1t" system agent size={size} ring={ring} />;
28 if (member.kind === "agent") return <AgentAvatar agent={member} size={size} ring={ring} />;
29 const avatar = <Avatar name={member.name} image={member.avatar} size={size} />;
30 if (!presence) return avatar;
31 return (
32 <WithPresence person={{ id: member.id, username: member.name }} size={size} ring={ring}>
33 {avatar}
34 </WithPresence>
35 );
36}
37
38/**
39 * AGENT beside the name an old message from an agent was posted under;
40 * DELETED AGENT, in the quiet colours, when chat says it was deleted.
41 */
42export function AgentPill({ className, deleted = false }: { className?: string; deleted?: boolean }) {
43 return (
44 <span
45 className={cn(
46 "inline-flex h-4 shrink-0 items-center rounded-sm bg-accent/15 px-1 text-[0.5625rem] font-semibold tracking-[0.06em] text-accent uppercase",
47 deleted && "bg-raised text-muted",
48 className,
49 )}
50 >
51 {deleted ? "Deleted agent" : "Agent"}
52 </span>
53 );
54}
55
56/**
57 * GUEST beside the name of someone who is not a member of the workspace
58 * whose chat this is: asked into a channel, or talking in a public one.
59 * Wherever people show (messages, members, mentions), so who is in the
60 * workspace is never in doubt.
61 */
62export function GuestPill({ className, workspace }: { className?: string; workspace?: string | null }) {
63 return (
64 <Hint label={`Not a member of ${workspace ?? "this workspace"}`}>
65 <span
66 className={cn(
67 "inline-flex h-4 shrink-0 items-center rounded-sm border border-line-strong px-1 text-[0.5625rem] font-semibold tracking-[0.06em] text-muted uppercase",
68 className,
69 )}
70 >
71 Guest
72 </span>
73 </Hint>
74 );
75}