feat: After the voice in the new conversation window is played, jump to the tab of the conversation #1877 (#2440)

### What problem does this PR solve?

feat: After the voice in the new conversation window is played, jump to
the tab of the conversation #1877

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2024-09-14 17:19:04 +08:00 committed by GitHub
parent b94c15ef1e
commit 1621313c0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 31 deletions

View File

@ -2,10 +2,11 @@ import { useDeleteMessage, useFeedback } from '@/hooks/chat-hooks';
import { useSetModalState } from '@/hooks/common-hooks'; import { useSetModalState } from '@/hooks/common-hooks';
import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks'; import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks';
import { IFeedbackRequestBody } from '@/interfaces/request/chat'; import { IFeedbackRequestBody } from '@/interfaces/request/chat';
import { ConversationContext } from '@/pages/chat/context';
import { getMessagePureId } from '@/utils/chat'; import { getMessagePureId } from '@/utils/chat';
import { hexStringToUint8Array } from '@/utils/common-util'; import { hexStringToUint8Array } from '@/utils/common-util';
import { SpeechPlayer } from 'openai-speech-stream-player'; import { SpeechPlayer } from 'openai-speech-stream-player';
import { useCallback, useEffect, useRef, useState } from 'react'; import { useCallback, useContext, useEffect, useRef, useState } from 'react';
export const useSendFeedback = (messageId: string) => { export const useSendFeedback = (messageId: string) => {
const { visible, hideModal, showModal } = useSetModalState(); const { visible, hideModal, showModal } = useSetModalState();
@ -58,21 +59,24 @@ export const useSpeech = (content: string, audioBinary?: string) => {
const { read } = useSpeechWithSse(); const { read } = useSpeechWithSse();
const player = useRef<SpeechPlayer>(); const player = useRef<SpeechPlayer>();
const [isPlaying, setIsPlaying] = useState<boolean>(false); const [isPlaying, setIsPlaying] = useState<boolean>(false);
const callback = useContext(ConversationContext);
const initialize = useCallback(async () => { const initialize = useCallback(async () => {
player.current = new SpeechPlayer({ player.current = new SpeechPlayer({
audio: ref.current!, audio: ref.current!,
onPlaying: () => { onPlaying: () => {
setIsPlaying(true); setIsPlaying(true);
callback?.(true);
}, },
onPause: () => { onPause: () => {
setIsPlaying(false); setIsPlaying(false);
callback?.(false);
}, },
onChunkEnd: () => {}, onChunkEnd: () => {},
mimeType: 'audio/mpeg', mimeType: 'audio/mpeg',
}); });
await player.current.init(); await player.current.init();
}, []); }, [callback]);
const pause = useCallback(() => { const pause = useCallback(() => {
player.current?.pause(); player.current?.pause();

View File

@ -6,6 +6,7 @@ export interface PromptConfig {
parameters: Parameter[]; parameters: Parameter[];
prologue: string; prologue: string;
system: string; system: string;
tts?: boolean;
} }
export interface Parameter { export interface Parameter {

View File

@ -19,6 +19,7 @@ import {
} from '@/hooks/chat-hooks'; } from '@/hooks/chat-hooks';
import { useFetchUserInfo } from '@/hooks/user-setting-hooks'; import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
import { memo } from 'react'; import { memo } from 'react';
import { ConversationContext } from '../context';
import styles from './index.less'; import styles from './index.less';
const ChatContainer = () => { const ChatContainer = () => {
@ -26,15 +27,16 @@ const ChatContainer = () => {
const { data: conversation } = useFetchNextConversation(); const { data: conversation } = useFetchNextConversation();
const { const {
value,
ref, ref,
loading, loading,
sendLoading, sendLoading,
derivedMessages, derivedMessages,
handleInputChange, handleInputChange,
handlePressEnter, handlePressEnter,
value,
regenerateMessage, regenerateMessage,
removeMessageById, removeMessageById,
redirectToNewConversation,
} = useSendNextMessage(); } = useSendNextMessage();
const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } = const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
@ -52,6 +54,7 @@ const ChatContainer = () => {
<Flex flex={1} vertical className={styles.messageContainer}> <Flex flex={1} vertical className={styles.messageContainer}>
<div> <div>
<Spin spinning={loading}> <Spin spinning={loading}>
<ConversationContext.Provider value={redirectToNewConversation}>
{derivedMessages?.map((message, i) => { {derivedMessages?.map((message, i) => {
return ( return (
<MessageItem <MessageItem
@ -79,6 +82,7 @@ const ChatContainer = () => {
></MessageItem> ></MessageItem>
); );
})} })}
</ConversationContext.Provider>
</Spin> </Spin>
</div> </div>
<div ref={ref} /> <div ref={ref} />

View File

@ -0,0 +1,5 @@
import { createContext } from 'react';
export const ConversationContext = createContext<
null | ((isPlaying: boolean) => void)
>(null);

View File

@ -32,6 +32,7 @@ import {
useCallback, useCallback,
useEffect, useEffect,
useMemo, useMemo,
useRef,
useState, useState,
} from 'react'; } from 'react';
import { useSearchParams } from 'umi'; import { useSearchParams } from 'umi';
@ -340,6 +341,17 @@ export const useSendNextMessage = () => {
removeMessageById, removeMessageById,
removeMessagesAfterCurrentMessage, removeMessagesAfterCurrentMessage,
} = useSelectNextMessages(); } = useSelectNextMessages();
const { data: dialog } = useFetchNextDialog();
const currentConversationIdRef = useRef<string>('');
const redirectToNewConversation = useCallback(
(isPlaying: boolean) => {
if (!conversationId && dialog?.prompt_config?.tts && !isPlaying) {
handleClickConversation(currentConversationIdRef.current);
}
},
[dialog, handleClickConversation, conversationId],
);
const sendMessage = useCallback( const sendMessage = useCallback(
async ({ async ({
@ -365,7 +377,9 @@ export const useSendNextMessage = () => {
if (currentConversationId) { if (currentConversationId) {
console.info('111'); console.info('111');
// new conversation // new conversation
if (!dialog?.prompt_config?.tts) {
handleClickConversation(currentConversationId); handleClickConversation(currentConversationId);
}
} else { } else {
console.info('222'); console.info('222');
// fetchConversation(conversationId); // fetchConversation(conversationId);
@ -373,6 +387,7 @@ export const useSendNextMessage = () => {
} }
}, },
[ [
dialog,
derivedMessages, derivedMessages,
conversationId, conversationId,
handleClickConversation, handleClickConversation,
@ -390,6 +405,7 @@ export const useSendNextMessage = () => {
const data = await setConversation(message.content); const data = await setConversation(message.content);
if (data.retcode === 0) { if (data.retcode === 0) {
const id = data.data.id; const id = data.data.id;
currentConversationIdRef.current = id;
sendMessage({ sendMessage({
message, message,
currentConversationId: id, currentConversationId: id,
@ -463,6 +479,7 @@ export const useSendNextMessage = () => {
ref, ref,
derivedMessages, derivedMessages,
removeMessageById, removeMessageById,
redirectToNewConversation,
}; };
}; };