Show a bot group's time beside the last message's play button
The timestamp no longer takes its own line under a bot group: it sits before the read-aloud button on the last message, after the needs-you chip when there is one. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -5,7 +5,6 @@ import type { BotFace, BotHue } from "@/src/dict/bot-dict";
|
|||||||
import type { BotWithLastMessage } from "@/src/types";
|
import type { BotWithLastMessage } from "@/src/types";
|
||||||
import type { MessageGroup } from "../(utils)/group-messages";
|
import type { MessageGroup } from "../(utils)/group-messages";
|
||||||
import BotMessageLine from "./bot-message-line";
|
import BotMessageLine from "./bot-message-line";
|
||||||
import GroupTimestamp from "./group-timestamp";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
bot: BotWithLastMessage;
|
bot: BotWithLastMessage;
|
||||||
@@ -13,7 +12,8 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plain text, no bubble. A 28px stone sits on the group's first line only.
|
* Plain text, no bubble. A 28px stone sits on the group's first line only;
|
||||||
|
* the group's time sits beside the last message's play button.
|
||||||
*/
|
*/
|
||||||
export default function BotMessageGroup({ bot, group }: Props) {
|
export default function BotMessageGroup({ bot, group }: Props) {
|
||||||
return (
|
return (
|
||||||
@@ -26,15 +26,15 @@ export default function BotMessageGroup({ bot, group }: Props) {
|
|||||||
className="-mt-1"
|
className="-mt-1"
|
||||||
/>
|
/>
|
||||||
<Stack className="min-w-0 grow gap-1! items-start">
|
<Stack className="min-w-0 grow gap-1! items-start">
|
||||||
{group.messages.map((message) => (
|
{group.messages.map((message, index) => (
|
||||||
<BotMessageLine
|
<BotMessageLine
|
||||||
key={message.id}
|
key={message.id}
|
||||||
message_id={message.id || null}
|
message_id={message.id || null}
|
||||||
text={message.text || ""}
|
text={message.text || ""}
|
||||||
needs_you={Boolean(message.needs_you)}
|
needs_you={Boolean(message.needs_you)}
|
||||||
|
at={index == group.messages.length - 1 ? group.at : undefined}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<GroupTimestamp at={group.at} />
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Row from "@moduletrace/twui/layout/Row";
|
|||||||
import Stack from "@moduletrace/twui/layout/Stack";
|
import Stack from "@moduletrace/twui/layout/Stack";
|
||||||
import linkComputerRefs from "@/src/utils/link-computer-refs";
|
import linkComputerRefs from "@/src/utils/link-computer-refs";
|
||||||
import { MessageMarkdownComponents } from "../(data)/message-markdown-components";
|
import { MessageMarkdownComponents } from "../(data)/message-markdown-components";
|
||||||
|
import GroupTimestamp from "./group-timestamp";
|
||||||
import NeedsYouChip from "./needs-you-chip";
|
import NeedsYouChip from "./needs-you-chip";
|
||||||
import SpeakMessageButton from "./speak-message-button";
|
import SpeakMessageButton from "./speak-message-button";
|
||||||
|
|
||||||
@@ -11,15 +12,21 @@ type Props = {
|
|||||||
message_id?: number | null;
|
message_id?: number | null;
|
||||||
text: string;
|
text: string;
|
||||||
needs_you?: boolean;
|
needs_you?: boolean;
|
||||||
|
/**
|
||||||
|
* The group's time, on the last message only: shown beside its play
|
||||||
|
* button.
|
||||||
|
*/
|
||||||
|
at?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One bot message, rendered from markdown (GFM; raw HTML is never
|
* One bot message, rendered from markdown (GFM; raw HTML is never
|
||||||
* rendered). Computers it names (`computerRef`) show as buttons that
|
* rendered). Computers it names (`computerRef`) show as buttons that
|
||||||
* switch the bot to them. A play button under it reads it aloud,
|
* switch the bot to them. A play button under it reads it aloud,
|
||||||
* disabled while the bot has no speech model.
|
* disabled while the bot has no speech model, with the group's time
|
||||||
|
* before it on the last message.
|
||||||
*/
|
*/
|
||||||
export default function BotMessageLine({ message_id, text, needs_you }: Props) {
|
export default function BotMessageLine({ message_id, text, needs_you, at }: Props) {
|
||||||
const can_speak = Boolean(message_id && text.trim());
|
const can_speak = Boolean(message_id && text.trim());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -32,9 +39,10 @@ export default function BotMessageLine({ message_id, text, needs_you }: Props) {
|
|||||||
{linkComputerRefs({ text })}
|
{linkComputerRefs({ text })}
|
||||||
</Markdown>
|
</Markdown>
|
||||||
</Stack>
|
</Stack>
|
||||||
{needs_you || can_speak ? (
|
{needs_you || can_speak || at ? (
|
||||||
<Row className="gap-2! items-center">
|
<Row className="gap-2! items-center">
|
||||||
{needs_you ? <NeedsYouChip /> : null}
|
{needs_you ? <NeedsYouChip /> : null}
|
||||||
|
{at ? <GroupTimestamp at={at} /> : null}
|
||||||
{can_speak ? (
|
{can_speak ? (
|
||||||
<SpeakMessageButton message_id={message_id!} />
|
<SpeakMessageButton message_id={message_id!} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
Reference in New Issue
Block a user