Skip to content

Commit 51b328c

Browse files
authoredMar 26, 2025
Merge pull request #4071 from elizaOS/tcm/text-animation
fix: gui text animation
2 parents fe2c463 + 3ed189f commit 51b328c

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed
 

‎packages/client/src/components/chat.tsx

+13-6
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ const MemoizedMessageContent = React.memo(MessageContent);
4343
function MessageContent({
4444
message,
4545
agentId,
46-
isLastMessage,
46+
shouldAnimate,
4747
}: {
4848
message: ContentWithUser;
4949
agentId: UUID;
50-
isLastMessage: boolean;
50+
shouldAnimate: boolean;
5151
}) {
5252
return (
5353
<div className="flex flex-col w-full">
@@ -77,7 +77,7 @@ function MessageContent({
7777
<div className="py-2">
7878
{message.name === USER_NAME ? (
7979
message.text
80-
) : isLastMessage && message.name !== USER_NAME ? (
80+
) : shouldAnimate ? (
8181
<AIWriter>{message.text}</AIWriter>
8282
) : (
8383
message.text
@@ -87,7 +87,7 @@ function MessageContent({
8787
message.thought &&
8888
(message.name === USER_NAME ? (
8989
message.thought
90-
) : isLastMessage && message.name !== USER_NAME ? (
90+
) : shouldAnimate ? (
9191
<AIWriter>
9292
<span className="italic text-muted-foreground">{message.thought}</span>
9393
</AIWriter>
@@ -167,6 +167,8 @@ export default function Page({
167167

168168
const socketIOManager = SocketIOManager.getInstance();
169169

170+
const animatedMessageIdRef = useRef<string | null>(null);
171+
170172
useEffect(() => {
171173
// Initialize Socket.io connection once with our entity ID
172174
socketIOManager.initialize(entityId, [agentId]);
@@ -226,6 +228,8 @@ export default function Page({
226228
return old;
227229
}
228230

231+
animatedMessageIdRef.current = newMessage.id;
232+
229233
return [...old, newMessage];
230234
}
231235
);
@@ -413,7 +417,10 @@ export default function Page({
413417
>
414418
{messages.map((message: ContentWithUser, index: number) => {
415419
const isUser = message.name === USER_NAME;
416-
420+
const shouldAnimate =
421+
index === messages.length - 1 &&
422+
message.name !== USER_NAME &&
423+
message.id === animatedMessageIdRef.current;
417424
return (
418425
<div
419426
key={`${message.id as string}-${message.createdAt}`}
@@ -443,7 +450,7 @@ export default function Page({
443450
<MemoizedMessageContent
444451
message={message}
445452
agentId={agentId}
446-
isLastMessage={index === messages.length - 1}
453+
shouldAnimate={shouldAnimate}
447454
/>
448455
</ChatBubble>
449456
</div>

‎packages/client/src/components/room.tsx

+13-6
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ const MemoizedMessageContent = React.memo(MessageContent);
3939

4040
function MessageContent({
4141
message,
42-
isLastMessage,
42+
shouldAnimate,
4343
isUser,
4444
}: {
4545
message: ContentWithUser;
46-
isLastMessage: boolean;
46+
shouldAnimate: boolean;
4747
isUser: boolean;
4848
}) {
4949
// Only log message details in development mode
@@ -84,7 +84,7 @@ function MessageContent({
8484
<div className="py-2">
8585
{isUser ? (
8686
message.text
87-
) : isLastMessage && !isUser ? (
87+
) : shouldAnimate ? (
8888
<AIWriter>{message.text}</AIWriter>
8989
) : (
9090
message.text
@@ -94,7 +94,7 @@ function MessageContent({
9494
<div>
9595
{isUser ? (
9696
message.thought
97-
) : isLastMessage && !isUser ? (
97+
) : shouldAnimate ? (
9898
<AIWriter>
9999
<span className="italic text-muted-foreground">{message.thought}</span>
100100
</AIWriter>
@@ -173,6 +173,8 @@ export default function Page({ serverId }: { serverId: UUID }) {
173173
const prevServerIdRef = useRef<UUID | null>(null);
174174
const prevActiveAgentIdsRef = useRef<UUID[]>([]);
175175

176+
const animatedMessageIdRef = useRef<string | null>(null);
177+
176178
const getAvatar = (agentId: string): string | null => {
177179
const rooms = roomsData?.get(serverId);
178180
const room = rooms?.find((room) => room.agentId === agentId);
@@ -278,6 +280,8 @@ export default function Page({ serverId }: { serverId: UUID }) {
278280
return old;
279281
}
280282

283+
animatedMessageIdRef.current = newMessage.id;
284+
281285
return [...old, newMessage];
282286
}
283287
);
@@ -481,7 +485,10 @@ export default function Page({ serverId }: { serverId: UUID }) {
481485
>
482486
{messages.map((message: ContentWithUser, index: number) => {
483487
const isUser = message.name === USER_NAME;
484-
488+
const shouldAnimate =
489+
index === messages.length - 1 &&
490+
message.name !== USER_NAME &&
491+
message.id === animatedMessageIdRef.current;
485492
return (
486493
<div
487494
key={`${message.id as string}-${message.createdAt}`}
@@ -509,7 +516,7 @@ export default function Page({ serverId }: { serverId: UUID }) {
509516

510517
<MemoizedMessageContent
511518
message={message}
512-
isLastMessage={index === messages.length - 1}
519+
shouldAnimate={shouldAnimate}
513520
isUser={isUser}
514521
/>
515522
</ChatBubble>

0 commit comments

Comments
 (0)