Show every bot of a chatroom in its rail icon
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
import Row from "@moduletrace/twui/layout/Row";
|
||||||
|
import Stack from "@moduletrace/twui/layout/Stack";
|
||||||
|
import type { ChatroomBot } from "@/src/types";
|
||||||
|
import ChatroomStone from "./chatroom-stone";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
bots: ChatroomBot[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The square the cluster fills (`w-7 h-7`), the size of a rail avatar.
|
||||||
|
*/
|
||||||
|
const ClusterSize = 28;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chatroom's bots packed into one avatar-sized square: the asking bot
|
||||||
|
* on top, the two below it in a triangle (four make a square, the rest
|
||||||
|
* are left out). Stones stay small and apart: never overlapping, in a
|
||||||
|
* badge or outlined. One bot fills the square alone.
|
||||||
|
*/
|
||||||
|
export default function ChatroomStoneCluster({ bots }: Props) {
|
||||||
|
const shown = bots.slice(0, 4);
|
||||||
|
const stone = Math.floor((ClusterSize - 2) / 2);
|
||||||
|
|
||||||
|
if (shown.length <= 1) {
|
||||||
|
return shown[0] ? <ChatroomStone bot={shown[0]} size={ClusterSize} /> : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const top = shown.length == 3 ? shown.slice(0, 1) : shown.slice(0, 2);
|
||||||
|
const bottom = shown.length == 2 ? [] : shown.slice(top.length);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack className="shrink-0 gap-0.5! items-center justify-center w-7 h-7">
|
||||||
|
<Row className="gap-0.5! flex-nowrap justify-center">
|
||||||
|
{top.map((bot) => (
|
||||||
|
<ChatroomStone key={bot.id} bot={bot} size={stone} />
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
{bottom.length ? (
|
||||||
|
<Row className="gap-0.5! flex-nowrap justify-center">
|
||||||
|
{bottom.map((bot) => (
|
||||||
|
<ChatroomStone key={bot.id} bot={bot} size={stone} />
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
) : null}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import Link from "@moduletrace/twui/layout/Link";
|
|||||||
import Span from "@moduletrace/twui/layout/Span";
|
import Span from "@moduletrace/twui/layout/Span";
|
||||||
import Stack from "@moduletrace/twui/layout/Stack";
|
import Stack from "@moduletrace/twui/layout/Stack";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
import ChatroomStone from "@/src/components/general/chatroom-stone";
|
import ChatroomStoneCluster from "@/src/components/general/chatroom-stone-cluster";
|
||||||
import type { ChatroomSummary } from "@/src/types";
|
import type { ChatroomSummary } from "@/src/types";
|
||||||
import chatroomStatusLine from "@/src/utils/chatroom-status-line";
|
import chatroomStatusLine from "@/src/utils/chatroom-status-line";
|
||||||
|
|
||||||
@@ -13,12 +13,11 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A chatroom in the rail, the same 48px row as a bot: the asking bot's
|
* A chatroom in the rail, the same 48px row as a bot: its bots' stones
|
||||||
* stone, the request and where it stands. Unread is said in words.
|
* in one avatar-sized cluster, the request and where it stands. Unread
|
||||||
|
* is said in words.
|
||||||
*/
|
*/
|
||||||
export default function RailChatroomRow({ chatroom, href, selected }: Props) {
|
export default function RailChatroomRow({ chatroom, href, selected }: Props) {
|
||||||
const requester = chatroom.bots[0];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={href}
|
href={href}
|
||||||
@@ -32,7 +31,7 @@ export default function RailChatroomRow({ chatroom, href, selected }: Props) {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Span className="mx-auto @rail:mx-0 inline-flex shrink-0">
|
<Span className="mx-auto @rail:mx-0 inline-flex shrink-0">
|
||||||
{requester ? <ChatroomStone bot={requester} size={28} /> : null}
|
<ChatroomStoneCluster bots={chatroom.bots} />
|
||||||
</Span>
|
</Span>
|
||||||
<Stack className="hidden @rail:flex grow min-w-0 gap-0!">
|
<Stack className="hidden @rail:flex grow min-w-0 gap-0!">
|
||||||
<Span className="text-sm font-bold leading-5 text-ink truncate w-full">
|
<Span className="text-sm font-bold leading-5 text-ink truncate w-full">
|
||||||
|
|||||||
Reference in New Issue
Block a user