Skip to content

Commit 5d1912f

Browse files
prakriti-solankeypraveshkumar1988
authored andcommitted
speech state (#426)
* speech state * Button Details changes
1 parent bb27bfe commit 5d1912f

File tree

6 files changed

+123
-131
lines changed

6 files changed

+123
-131
lines changed

frontend/src/components/ButtonWithToolTip.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const ButtonWithToolTip = ({
1111
className = '',
1212
label,
1313
loading,
14+
fill = 'filled',
1415
}: {
1516
text: string | React.ReactNode;
1617
children: React.ReactNode;
@@ -23,6 +24,7 @@ const ButtonWithToolTip = ({
2324
className?: string;
2425
loading?: boolean;
2526
label: string;
27+
fill?: 'filled' | 'outlined' | 'text';
2628
}) => {
2729
return (
2830
<Tip allowedPlacements={[placement]}>
@@ -34,6 +36,7 @@ const ButtonWithToolTip = ({
3436
disabled={disabled}
3537
className={className}
3638
loading={loading}
39+
fill={fill}
3740
>
3841
{children}
3942
</Button>

frontend/src/components/Chatbot.tsx

Lines changed: 61 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ import ReactMarkdown from 'react-markdown';
1919
import IconButtonWithToolTip from './IconButtonToolTip';
2020
import { buttonCaptions, tooltips } from '../utils/Constants';
2121
import useSpeechSynthesis from '../hooks/useSpeech';
22+
import ButtonWithToolTip from './ButtonWithToolTip';
2223

2324
const Chatbot: React.FC<ChatbotProps> = (props) => {
24-
const { messages: listMessages, setMessages: setListMessages, isLoading, isFullScreen } = props;
25+
const { messages: listMessages, setMessages: setListMessages, isLoading, isFullScreen, clear } = props;
2526
const [inputMessage, setInputMessage] = useState('');
2627
const [loading, setLoading] = useState<boolean>(isLoading);
2728
const { userCredentials } = useCredentials();
@@ -179,6 +180,13 @@ const Chatbot: React.FC<ChatbotProps> = (props) => {
179180
setLoading(() => listMessages.some((msg) => msg.isLoading || msg.isTyping));
180181
}, [listMessages]);
181182

183+
useEffect(() => {
184+
if (clear) {
185+
cancel();
186+
setListMessages((msgs) => msgs.map((msg) => ({ ...msg, speaking: false })));
187+
}
188+
}, [clear]);
189+
182190
const handleCopy = (message: string, id: number) => {
183191
copy(message);
184192
setListMessages((msgs) =>
@@ -276,66 +284,70 @@ const Chatbot: React.FC<ChatbotProps> = (props) => {
276284
{chat.datetime}
277285
</Typography>
278286
</div>
279-
{((chat.user === 'chatbot' && chat.id !== 2 && chat.sources?.length !== 0) || chat.isLoading) && (
280-
<div className='flex'>
281-
<IconButtonWithToolTip
282-
placement='top'
283-
clean
284-
text='Retrieval Information'
285-
label='Retrieval Information'
286-
disabled={chat.isTyping || chat.isLoading}
287-
onClick={() => {
288-
setModelModal(chat.model ?? '');
289-
setSourcesModal(chat.sources ?? []);
290-
setResponseTime(chat.response_time ?? 0);
291-
setChunkModal(chat.chunk_ids ?? []);
292-
setTokensUsed(chat.total_tokens ?? 0);
293-
setShowInfoModal(true);
294-
}}
295-
>
296-
<InformationCircleIconOutline className='w-4 h-4 inline-block' />
297-
</IconButtonWithToolTip>
298-
<IconButtonWithToolTip
299-
label='copy text'
300-
placement='top'
301-
clean
302-
text={chat.copying ? tooltips.copied : tooltips.copy}
303-
onClick={() => handleCopy(chat.message, chat.id)}
304-
disabled={chat.isTyping || chat.isLoading}
305-
>
306-
<ClipboardDocumentIconOutline className='w-4 h-4 inline-block' />
307-
</IconButtonWithToolTip>
308-
{copyMessageId === chat.id && (
309-
<>
310-
<span className='pt-4 text-xs'>Copied!</span>
311-
<span style={{ display: 'none' }}>{value}</span>
312-
</>
313-
)}
314-
{supported && chat.speaking ? (
287+
{chat.user === 'chatbot' &&
288+
chat.id !== 2 &&
289+
chat.sources?.length !== 0 &&
290+
!chat.isLoading &&
291+
!chat.isTyping && (
292+
<div className='flex inline-block'>
293+
<ButtonWithToolTip
294+
className='w-4 h-4 inline-block p-6 mt-1.5'
295+
fill='text'
296+
placement='top'
297+
clean
298+
text='Retrieval Information'
299+
label='Retrieval Information'
300+
disabled={chat.isTyping || chat.isLoading}
301+
onClick={() => {
302+
setModelModal(chat.model ?? '');
303+
setSourcesModal(chat.sources ?? []);
304+
setResponseTime(chat.response_time ?? 0);
305+
setChunkModal(chat.chunk_ids ?? []);
306+
setTokensUsed(chat.total_tokens ?? 0);
307+
setShowInfoModal(true);
308+
}}
309+
>
310+
{' '}
311+
{buttonCaptions.details}
312+
</ButtonWithToolTip>
315313
<IconButtonWithToolTip
314+
label='copy text'
316315
placement='top'
317-
label='text to speak'
318316
clean
319-
onClick={() => handleCancel(chat.id)}
320-
text={chat.speaking ? tooltips.stopSpeaking : tooltips.textTospeech}
317+
text={chat.copying ? tooltips.copied : tooltips.copy}
318+
onClick={() => handleCopy(chat.message, chat.id)}
321319
disabled={chat.isTyping || chat.isLoading}
322320
>
323-
<SpeakerXMarkIconOutline className='w-4 h-4 inline-block' />
321+
<ClipboardDocumentIconOutline className='w-4 h-4 inline-block' />
324322
</IconButtonWithToolTip>
325-
) : (
323+
{copyMessageId === chat.id && (
324+
<>
325+
<span className='pt-4 text-xs'>Copied!</span>
326+
<span style={{ display: 'none' }}>{value}</span>
327+
</>
328+
)}
326329
<IconButtonWithToolTip
327330
placement='top'
328331
clean
329-
onClick={() => handleSpeak(chat.message, chat.id)}
332+
onClick={() => {
333+
if (chat.speaking) {
334+
handleCancel(chat.id);
335+
} else {
336+
handleSpeak(chat.message, chat.id);
337+
}
338+
}}
330339
text={chat.speaking ? tooltips.stopSpeaking : tooltips.textTospeech}
331-
disabled={chat.isTyping || chat.isLoading}
332-
label='speech'
340+
disabled={listMessages.some((msg) => msg.speaking && msg.id !== chat.id)}
341+
label={chat.speaking ? 'stop speaking' : 'text to speech'}
333342
>
334-
<SpeakerWaveIconOutline className='w-4 h-4 inline-block' />
343+
{chat.speaking ? (
344+
<SpeakerXMarkIconOutline className='w-4 h-4 inline-block' />
345+
) : (
346+
<SpeakerWaveIconOutline className='w-4 h-4 inline-block' />
347+
)}
335348
</IconButtonWithToolTip>
336-
)}
337-
</div>
338-
)}
349+
</div>
350+
)}
339351
</div>
340352
</Widget>
341353
</div>

frontend/src/components/HoverableLink.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import React, { useState, useEffect, useRef } from 'react';
22
import { HoverableLinkProps } from '../types';
3-
43
const HoverableLink: React.FC<HoverableLinkProps> = ({ url, children }) => {
54
const [hovering, setHovering] = useState(false);
65
const [iframeSrc, setIframeSrc] = useState<string>('');
76
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
87
const popupRef = useRef<HTMLDivElement>(null);
9-
108
useEffect(() => {
119
let timer: NodeJS.Timeout;
1210
if (hovering) {
@@ -44,9 +42,7 @@ const HoverableLink: React.FC<HoverableLinkProps> = ({ url, children }) => {
4442
onMouseMove={handleMouseMove}
4543
onMouseLeave={handleMouseLeave}
4644
>
47-
<a href={url} target='_blank' rel='noopener noreferrer'>
48-
{children}
49-
</a>
45+
{children}
5046
{hovering && (
5147
<div
5248
className='popup'
@@ -68,6 +64,7 @@ const HoverableLink: React.FC<HoverableLinkProps> = ({ url, children }) => {
6864
)}
6965
</div>
7066
)}
67+
<a href={url} target='_blank' rel='noopener noreferrer' />
7168
</div>
7269
);
7370
};

0 commit comments

Comments
 (0)