Skip to content

Commit 26bec2d

Browse files
authored
fix(ui): improve last message height computation (#1470)
Signed-off-by: Petr Kadlec <petr@puradesign.cz>
1 parent 5205fbd commit 26bec2d

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

apps/agentstack-ui/src/modules/runs/chat/ChatAgentMessage.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ import classes from './ChatAgentMessage.module.scss';
2727
interface Props {
2828
message: UIAgentMessage;
2929
isLast?: boolean;
30+
isFirst?: boolean;
3031
containerScrollableRef?: RefObject<HTMLDivElement | null>;
31-
onShow?: () => void;
3232
}
3333

3434
export function ChatAgentMessage(props: Props) {
@@ -39,16 +39,12 @@ export function ChatAgentMessage(props: Props) {
3939
);
4040
}
4141

42-
function Message({ message, isLast, containerScrollableRef, onShow }: Props) {
42+
function Message({ message, isLast, isFirst, containerScrollableRef }: Props) {
4343
const contentRef = useRef<HTMLDivElement>(null);
4444
const rootRef = useRef<HTMLDivElement>(null);
4545

4646
const { props } = useMessageInteractionProps();
4747

48-
useEffect(() => {
49-
onShow?.();
50-
}, [onShow]);
51-
5248
const updateHeight = useCallback(() => {
5349
if (!containerScrollableRef?.current || !rootRef.current) {
5450
return;
@@ -63,15 +59,20 @@ function Message({ message, isLast, containerScrollableRef, onShow }: Props) {
6359
const messagesElem = listItemElem?.parentElement;
6460
const prevMessageElem = listItemElem?.nextElementSibling; // Messages are in reverse order
6561

66-
if (prevMessageElem instanceof HTMLLIElement && messagesElem) {
67-
const nextSiblingHeight = prevMessageElem?.offsetHeight ?? 0;
68-
const rowGap = parseFloat(window.getComputedStyle(messagesElem).rowGap);
62+
if (messagesElem) {
63+
const nextSiblingHeight =
64+
prevMessageElem instanceof HTMLLIElement
65+
? prevMessageElem.offsetHeight
66+
: isFirst
67+
? MESSAGE_PLACEHOLDER_HEIGHT
68+
: 0;
69+
const rowGap = nextSiblingHeight ? parseFloat(window.getComputedStyle(messagesElem).rowGap) : 0;
6970

7071
const availableHeight = Math.max(0, containerHeight - nextSiblingHeight - rowGap);
7172
rootRef.current.style.minBlockSize = rem(availableHeight);
7273
}
7374
}
74-
}, [isLast, containerScrollableRef]);
75+
}, [containerScrollableRef, isLast, isFirst]);
7576

7677
useEffect(() => {
7778
updateHeight();
@@ -119,3 +120,5 @@ function Message({ message, isLast, containerScrollableRef, onShow }: Props) {
119120
</div>
120121
);
121122
}
123+
124+
const MESSAGE_PLACEHOLDER_HEIGHT = 46; // Height in px to reserve for the last user message to avoid layout shift

apps/agentstack-ui/src/modules/runs/chat/ChatMessagesView.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,28 +52,30 @@ export function ChatMessagesView() {
5252
{messages.map((message, idx) => {
5353
const isUser = isUserMessage(message);
5454
const isAgent = isAgentMessage(message);
55-
const isLast = idx == 0; // messages are displayed in reverse order
55+
56+
// messages are displayed in reverse order
57+
const isLast = idx === 0;
58+
const isFirst = idx === messages.length - 1;
5659

5760
return (
58-
<li key={message.id} className={classes.message}>
61+
<li key={message.id}>
5962
{isUser && <ChatUserMessage message={message} />}
6063

6164
{isAgent && (
6265
<ChatAgentMessage
6366
message={message}
64-
onShow={isLast ? scrollToBottom : undefined}
6567
isLast={isLast}
68+
isFirst={isFirst}
6669
containerScrollableRef={scrollElementRef}
6770
/>
6871
)}
6972

7073
{isLast && <div ref={observeElementRef} />}
74+
{isFirst && hasNextPage && <div ref={fetchNextPageInViewAnchorRef} />}
7175
</li>
7276
);
7377
})}
7478

75-
{hasNextPage && <li ref={fetchNextPageInViewAnchorRef}> </li>}
76-
7779
{isFetchingNextPage && (
7880
<li className={classes.loading}>
7981
<InlineLoading description="Loading more messages..." />

0 commit comments

Comments
 (0)