in dialogflow-messenger/src/App.tsx [20:159]
function App({ domElement }: { domElement: Element }) {
const {
"chat-title": chatTitle,
'language-code': languageCode,
'api-uri': apiURI,
'chat-icon': chatIcon,
'expand': expand,
} = getAttributes(domElement);
const [open, setOpen] = useState(expand != null);
const [value, setValue] = useState('');
const [error, setError] = useState(false);
const [messages, setMessages] = useState<Message[]>([]);
const messagesEndRef = useRef<HTMLDivElement>(null)
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
}
useEffect(() => {
if (error) {
setTimeout(() => {
setError(false);
}, 2000)
}
}, [error])
const updateAgentMessage = (response: APIResponse, fromEvent?: boolean) => {
setMessages(prevMessages => {
if (JSON.stringify(response) === '{}') {
const messagesCopy = prevMessages.filter(m => m.text !== '...');
setError(true);
return messagesCopy;
}
const messagesCopy = [...prevMessages];
const {queryResult} = response
const {text: messageSent = '', responseMessages = []} = queryResult
let lastAgentIndex = messagesCopy.length - 1;
while (lastAgentIndex > 0 && (
fromEvent ?
messagesCopy[lastAgentIndex].text !== '...'
:
messagesCopy[lastAgentIndex].id !== messageSent
)) {
lastAgentIndex--;
}
if (messagesCopy[lastAgentIndex].id === messageSent || (fromEvent && messagesCopy[lastAgentIndex].text === '...')) {
const responseMessage = responseMessages[0]
if (responseMessage.text) {
const responseText = responseMessage?.text?.text
messagesCopy[lastAgentIndex].text = responseText[0];
messagesCopy[lastAgentIndex].id = undefined;
} else if (responseMessage.payload) {
const {richContent = []} = responseMessage.payload;
const contentList = richContent[0]
messagesCopy[lastAgentIndex].text = undefined;
messagesCopy[lastAgentIndex].id = undefined;
messagesCopy[lastAgentIndex].payload = contentList;
}
}
for (let i = 1; i < responseMessages.length; i++) {
const message = responseMessages[i];
if (message.text) {
const responseText = message?.text?.text
responseText && messagesCopy.push({type: 'agent', text: responseText[0]})
} else if (message.payload) {
const {richContent = []} = message.payload;
const contentList = richContent[0]
contentList && messagesCopy.push({type: 'agent', payload: contentList})
}
}
return messagesCopy
})
scrollToBottom();
}
const addUserMessage = async () => {
const textVal = value
addMessage({type: 'user', text: textVal})
addMessage({type: 'agent', text: '...', id: textVal})
const response = await handleResponse(apiURI, languageCode, value)
console.log(response)
updateAgentMessage(response)
}
const addMessage = ({type, text, id}: Message) => {
setMessages(prevMessages => ([...prevMessages, {type, text, id}]));
setValue('');
}
useEffect(() => {
scrollToBottom()
}, [messages.length]);
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
addUserMessage();
}
}
const renderMessage = (message: Message, i: number) => {
if (message.text) {
return <Text key={i} message={message} />
} else if (message.payload) {
return <ContentCard key={i} message={message} apiURI={apiURI} addMessage={addMessage} updateAgentMessage={updateAgentMessage} languageCode={languageCode} />
}
return null;
}
return (
<div className="App">
<Messenger opened={open}>
<TitleBar>
{chatTitle}
</TitleBar>
<TextWindow>
<MessageListWrapper>
<Error open={error}>
Something went wrong, please try again.
</Error>
<MessageList>
{messages.map((message, i) => renderMessage(message, i)
)}
<div ref={messagesEndRef} />
</MessageList>
</MessageListWrapper>
</TextWindow>
<InputField>
<TextInput id="text-input" type='text' value={value} onKeyDown={handleKeyDown} onChange={(event) => setValue(event.target.value)} placeholder="Ask something..." />