refactor(web): share user content stack
This commit is contained in:
@@ -153,6 +153,29 @@ function projectUserText(text: string): ReactNode {
|
|||||||
return <>{parts}</>
|
return <>{parts}</>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function UserContentStack({ parts, imageLoader, steering = false, t, truncated }: {
|
||||||
|
parts: ReturnType<typeof contentParts>
|
||||||
|
imageLoader: ImageLoader
|
||||||
|
steering?: boolean
|
||||||
|
t: ChatViewSlotProps['t']
|
||||||
|
truncated: (total: number) => string
|
||||||
|
}) {
|
||||||
|
const { text, images, rest } = parts
|
||||||
|
const showBubble = steering || text !== '' || rest.length > 0
|
||||||
|
return (
|
||||||
|
<div className={css.userStack}>
|
||||||
|
<ImageGallery images={images} load={imageLoader} align="end" t={t} />
|
||||||
|
{showBubble && <div className={css.bubble}>
|
||||||
|
{steering && <span className={css.badge}>{t('message.steering')}</span>}
|
||||||
|
{projectUserText(text)}
|
||||||
|
{rest.map((block, i) => (
|
||||||
|
<JsonBlock key={i} label={t('message.extraBlock')} payload={block} truncatedLabel={truncated} />
|
||||||
|
))}
|
||||||
|
</div>}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const MessageItem = memo(function MessageItem({
|
export const MessageItem = memo(function MessageItem({
|
||||||
node, loadImage, retryActive = false, onFork, t,
|
node, loadImage, retryActive = false, onFork, t,
|
||||||
}: MessageItemProps) {
|
}: MessageItemProps) {
|
||||||
@@ -160,20 +183,12 @@ export const MessageItem = memo(function MessageItem({
|
|||||||
const truncated = (total: number): string => t('json.truncated', { total })
|
const truncated = (total: number): string => t('json.truncated', { total })
|
||||||
switch (node.kind) {
|
switch (node.kind) {
|
||||||
case 'user': {
|
case 'user': {
|
||||||
const { text, images, rest } = contentParts(node.content)
|
const parts = contentParts(node.content)
|
||||||
return (
|
return (
|
||||||
<div className={css.userRow}>
|
<div className={css.userRow}>
|
||||||
<div className={css.userStack}>
|
<UserContentStack parts={parts} imageLoader={imageLoader} t={t} truncated={truncated} />
|
||||||
<ImageGallery images={images} load={imageLoader} align="end" t={t} />
|
|
||||||
{(text !== '' || rest.length > 0) && <div className={css.bubble}>
|
|
||||||
{projectUserText(text)}
|
|
||||||
{rest.map((block, i) => (
|
|
||||||
<JsonBlock key={i} label={t('message.extraBlock')} payload={block} truncatedLabel={truncated} />
|
|
||||||
))}
|
|
||||||
</div>}
|
|
||||||
</div>
|
|
||||||
<MessageIconActions
|
<MessageIconActions
|
||||||
text={text}
|
text={parts.text}
|
||||||
time={node.time}
|
time={node.time}
|
||||||
clock="start"
|
clock="start"
|
||||||
onBranch={onFork === undefined ? undefined : () => { onFork(node.seq) }}
|
onBranch={onFork === undefined ? undefined : () => { onFork(node.seq) }}
|
||||||
@@ -184,19 +199,10 @@ export const MessageItem = memo(function MessageItem({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
case 'steering': {
|
case 'steering': {
|
||||||
const { text, images, rest } = contentParts(node.content)
|
const parts = contentParts(node.content)
|
||||||
return (
|
return (
|
||||||
<div className={css.userRow}>
|
<div className={css.userRow}>
|
||||||
<div className={css.userStack}>
|
<UserContentStack parts={parts} imageLoader={imageLoader} steering t={t} truncated={truncated} />
|
||||||
<ImageGallery images={images} load={imageLoader} align="end" t={t} />
|
|
||||||
<div className={css.bubble}>
|
|
||||||
<span className={css.badge}>{t('message.steering')}</span>
|
|
||||||
{projectUserText(text)}
|
|
||||||
{rest.map((block, i) => (
|
|
||||||
<JsonBlock key={i} label={t('message.extraBlock')} payload={block} truncatedLabel={truncated} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user