Skip to content

Commit 161a993

Browse files
chrisbmarCAWilson94
authored andcommitted
[Agent Builder] Add typewriter effect to conversation title (elastic#234526)
1 parent 546f954 commit 161a993

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

x-pack/platform/plugins/shared/onechat/public/application/components/conversations/conversation_title.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* 2.0.
66
*/
77

8-
import React from 'react';
8+
import React, { useState, useEffect } from 'react';
99
import { EuiTitle, EuiPageHeaderSection, useEuiTheme } from '@elastic/eui';
1010
import { css } from '@emotion/react';
1111
import { i18n } from '@kbn/i18n';
@@ -15,6 +15,9 @@ export const ConversationTitle: React.FC<{}> = () => {
1515
const { euiTheme } = useEuiTheme();
1616
const { title, isLoading } = useConversationTitle();
1717

18+
const [previousTitle, setPreviousTitle] = useState<string>('');
19+
const [currentText, setCurrentText] = useState<string>('');
20+
1821
const labels = {
1922
ariaLabel: i18n.translate('xpack.onechat.conversationTitle.ariaLabel', {
2023
defaultMessage: 'Conversation title',
@@ -27,6 +30,32 @@ export const ConversationTitle: React.FC<{}> = () => {
2730
),
2831
};
2932

33+
useEffect(() => {
34+
if (isLoading) return;
35+
36+
const fullText = title || labels.newConversationDisplay;
37+
38+
// Typewriter effect: only when transitioning from "New conversation" to actual title
39+
if (previousTitle === labels.newConversationDisplay && title) {
40+
if (currentText.length < fullText.length) {
41+
// start typewriter effect
42+
const typingSpeed = 50;
43+
const timeout = setTimeout(() => {
44+
setCurrentText(fullText.substring(0, currentText.length + 1));
45+
}, typingSpeed);
46+
47+
return () => clearTimeout(timeout);
48+
}
49+
} else if (title && title !== previousTitle) {
50+
// Normal title change: set immediately without typewriter effect I.e. when changing from one conversation to another
51+
setCurrentText(fullText);
52+
}
53+
// always track the previous title
54+
setPreviousTitle(fullText);
55+
}, [title, currentText, labels.newConversationDisplay, isLoading, previousTitle]);
56+
57+
const titleDisplayText = currentText || previousTitle;
58+
3059
const sectionStyles = css`
3160
display: flex;
3261
flex-direction: row;
@@ -37,7 +66,7 @@ export const ConversationTitle: React.FC<{}> = () => {
3766
<EuiPageHeaderSection css={sectionStyles}>
3867
{!isLoading && (
3968
<EuiTitle aria-label={labels.ariaLabel} size="xxs">
40-
<h1>{title || labels.newConversationDisplay}</h1>
69+
<h1>{titleDisplayText}</h1>
4170
</EuiTitle>
4271
)}
4372
</EuiPageHeaderSection>

0 commit comments

Comments
 (0)