From a34d4dccb29e37a149d05119e4db9f4c7840e58d Mon Sep 17 00:00:00 2001 From: Mirza Hanan Date: Tue, 6 Aug 2024 21:46:23 +0500 Subject: [PATCH] fix(add-button): add audio button in ai chat --- public/svg-icons/AiPauseIcon.svg | 3 ++ public/svg-icons/AiPlayIcon.svg | 3 ++ .../App/SideBar/AiSummary/index.tsx | 53 +++++++++++++++++++ src/components/App/index.tsx | 15 ++++++ src/components/Icons/AiPauseIcon.tsx | 19 +++++++ src/components/Icons/AiPlayIcon.tsx | 19 +++++++ src/types/index.ts | 6 +++ 7 files changed, 118 insertions(+) create mode 100644 public/svg-icons/AiPauseIcon.svg create mode 100644 public/svg-icons/AiPlayIcon.svg create mode 100644 src/components/Icons/AiPauseIcon.tsx create mode 100644 src/components/Icons/AiPlayIcon.tsx diff --git a/public/svg-icons/AiPauseIcon.svg b/public/svg-icons/AiPauseIcon.svg new file mode 100644 index 000000000..685c4b604 --- /dev/null +++ b/public/svg-icons/AiPauseIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/svg-icons/AiPlayIcon.svg b/public/svg-icons/AiPlayIcon.svg new file mode 100644 index 000000000..7cc45bcfe --- /dev/null +++ b/public/svg-icons/AiPlayIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/App/SideBar/AiSummary/index.tsx b/src/components/App/SideBar/AiSummary/index.tsx index b76fa05d8..a7534af7c 100644 --- a/src/components/App/SideBar/AiSummary/index.tsx +++ b/src/components/App/SideBar/AiSummary/index.tsx @@ -1,6 +1,8 @@ import Button from '@mui/material/Button' import { useEffect, useRef, useState } from 'react' import styled from 'styled-components' +import AiPauseIcon from '~/components/Icons/AiPauseIcon' +import AiPlayIcon from '~/components/Icons/AiPlayIcon' import ChevronDownIcon from '~/components/Icons/ChevronDownIcon' import ChevronUpIcon from '~/components/Icons/ChevronUpIcon' import { Flex } from '~/components/common/Flex' @@ -43,6 +45,8 @@ export const AiSummary = ({ question, response, refId }: Props) => { const ref = useRef(null) const [collapsed, setCollapsed] = useState(false) const { setAiSummaryAnswer } = useAiSummaryStore((s) => s) + const audioRef = useRef(null) + const [isPlaying, setIsPlaying] = useState(false) useEffect(() => { if (ref.current) { @@ -60,10 +64,25 @@ export const AiSummary = ({ question, response, refId }: Props) => { } } + const handleToggleAudio = () => { + if (audioRef.current) { + if (isPlaying) { + audioRef.current.pause() + } else { + audioRef.current.play() + } + + setIsPlaying(!isPlaying) + } + } + return ( {question} + {!response.audio_en && ( + {isPlaying ? : } + )} {collapsed ? : } {!collapsed && ( @@ -86,6 +105,11 @@ export const AiSummary = ({ question, response, refId }: Props) => { {(response?.sources || []).length ? : null} )} + {response.audio_en && ( + + + + )} ) } @@ -119,3 +143,32 @@ const CollapseButton = styled(Button)` color: white; } ` + +const AudioButton = styled(Button)` + &&.MuiButton-root { + background-color: ${colors.COLLAPSE_BUTTON}; + border: none; + cursor: pointer; + flex-shrink: 0; + padding: 0px; + width: 27px; + height: 26px; + min-width: 26px; + border-radius: 6px; + display: flex; + align-items: center; + justify-content: center; + margin-top: 1px; + margin-right: 10px; + } + + svg { + width: 29px; + height: 12px; + color: white; + } +` + +const StyledAudio = styled.audio` + display: none; +` diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 4bb79f001..0d6277a88 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -19,6 +19,7 @@ import { useTeachStore } from '~/stores/useTeachStore' import { useUserStore } from '~/stores/useUserStore' import { AiSummaryAnswerResponse, + AiSummaryAudioResponse, AiSummaryQuestionsResponse, AiSummarySourcesResponse, ExtractedEntitiesResponse, @@ -131,6 +132,15 @@ export const App = () => { [setAiSummaryAnswer], ) + const handleAiSummaryAudio = useCallback( + (data: AiSummaryAudioResponse) => { + if (data.ref_id) { + setAiSummaryAnswer(data.ref_id, { audio_en: data.audio_en }) + } + }, + [setAiSummaryAnswer], + ) + const handleAiRelevantQuestions = useCallback( (data: AiSummaryQuestionsResponse) => { if (data.ref_id) { @@ -201,6 +211,10 @@ export const App = () => { if (realtimeGraphFeatureFlag) { socket.on('new_node_created', handleNewNodeCreated) } + + if (chatInterfaceFeatureFlag) { + socket.on('answeraudiohook', handleAiSummaryAudio) + } } return () => { @@ -218,6 +232,7 @@ export const App = () => { handleAiRelevantQuestions, handleAiSources, handleExtractedEntities, + handleAiSummaryAudio, ]) return ( diff --git a/src/components/Icons/AiPauseIcon.tsx b/src/components/Icons/AiPauseIcon.tsx new file mode 100644 index 000000000..2c8351c5e --- /dev/null +++ b/src/components/Icons/AiPauseIcon.tsx @@ -0,0 +1,19 @@ +/* eslint-disable */ +import React from 'react'; + +const AiPauseIcon: React.FC> = (props) => ( + + + +); + +export default AiPauseIcon; diff --git a/src/components/Icons/AiPlayIcon.tsx b/src/components/Icons/AiPlayIcon.tsx new file mode 100644 index 000000000..0796bd62f --- /dev/null +++ b/src/components/Icons/AiPlayIcon.tsx @@ -0,0 +1,19 @@ +/* eslint-disable */ +import React from 'react'; + +const AiPlayIcon: React.FC> = (props) => ( + + + +); + +export default AiPlayIcon; diff --git a/src/types/index.ts b/src/types/index.ts index 92927aaa1..b94ee5ceb 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -314,6 +314,7 @@ export type AIEntity = { hasBeenRendered?: boolean entities?: ExtractedEntity[] shouldRender?: boolean + audio_en?: string } export interface ExtractedEntity { @@ -326,3 +327,8 @@ export interface ExtractedEntitiesResponse { question: string entities: ExtractedEntity[] } + +export type AiSummaryAudioResponse = { + ref_id: string + audio_en: string +}