balibabu commited on
Commit
2b66f8c
·
1 Parent(s): 9cb9cc1

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

Browse files

### 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)

web/src/components/message-item/hooks.ts CHANGED
@@ -2,10 +2,11 @@ import { useDeleteMessage, useFeedback } from '@/hooks/chat-hooks';
2
  import { useSetModalState } from '@/hooks/common-hooks';
3
  import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks';
4
  import { IFeedbackRequestBody } from '@/interfaces/request/chat';
 
5
  import { getMessagePureId } from '@/utils/chat';
6
  import { hexStringToUint8Array } from '@/utils/common-util';
7
  import { SpeechPlayer } from 'openai-speech-stream-player';
8
- import { useCallback, useEffect, useRef, useState } from 'react';
9
 
10
  export const useSendFeedback = (messageId: string) => {
11
  const { visible, hideModal, showModal } = useSetModalState();
@@ -58,21 +59,24 @@ export const useSpeech = (content: string, audioBinary?: string) => {
58
  const { read } = useSpeechWithSse();
59
  const player = useRef<SpeechPlayer>();
60
  const [isPlaying, setIsPlaying] = useState<boolean>(false);
 
61
 
62
  const initialize = useCallback(async () => {
63
  player.current = new SpeechPlayer({
64
  audio: ref.current!,
65
  onPlaying: () => {
66
  setIsPlaying(true);
 
67
  },
68
  onPause: () => {
69
  setIsPlaying(false);
 
70
  },
71
  onChunkEnd: () => {},
72
  mimeType: 'audio/mpeg',
73
  });
74
  await player.current.init();
75
- }, []);
76
 
77
  const pause = useCallback(() => {
78
  player.current?.pause();
 
2
  import { useSetModalState } from '@/hooks/common-hooks';
3
  import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks';
4
  import { IFeedbackRequestBody } from '@/interfaces/request/chat';
5
+ import { ConversationContext } from '@/pages/chat/context';
6
  import { getMessagePureId } from '@/utils/chat';
7
  import { hexStringToUint8Array } from '@/utils/common-util';
8
  import { SpeechPlayer } from 'openai-speech-stream-player';
9
+ import { useCallback, useContext, useEffect, useRef, useState } from 'react';
10
 
11
  export const useSendFeedback = (messageId: string) => {
12
  const { visible, hideModal, showModal } = useSetModalState();
 
59
  const { read } = useSpeechWithSse();
60
  const player = useRef<SpeechPlayer>();
61
  const [isPlaying, setIsPlaying] = useState<boolean>(false);
62
+ const callback = useContext(ConversationContext);
63
 
64
  const initialize = useCallback(async () => {
65
  player.current = new SpeechPlayer({
66
  audio: ref.current!,
67
  onPlaying: () => {
68
  setIsPlaying(true);
69
+ callback?.(true);
70
  },
71
  onPause: () => {
72
  setIsPlaying(false);
73
+ callback?.(false);
74
  },
75
  onChunkEnd: () => {},
76
  mimeType: 'audio/mpeg',
77
  });
78
  await player.current.init();
79
+ }, [callback]);
80
 
81
  const pause = useCallback(() => {
82
  player.current?.pause();
web/src/interfaces/database/chat.ts CHANGED
@@ -6,6 +6,7 @@ export interface PromptConfig {
6
  parameters: Parameter[];
7
  prologue: string;
8
  system: string;
 
9
  }
10
 
11
  export interface Parameter {
 
6
  parameters: Parameter[];
7
  prologue: string;
8
  system: string;
9
+ tts?: boolean;
10
  }
11
 
12
  export interface Parameter {
web/src/pages/chat/chat-container/index.tsx CHANGED
@@ -19,6 +19,7 @@ import {
19
  } from '@/hooks/chat-hooks';
20
  import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
21
  import { memo } from 'react';
 
22
  import styles from './index.less';
23
 
24
  const ChatContainer = () => {
@@ -26,15 +27,16 @@ const ChatContainer = () => {
26
  const { data: conversation } = useFetchNextConversation();
27
 
28
  const {
 
29
  ref,
30
  loading,
31
  sendLoading,
32
  derivedMessages,
33
  handleInputChange,
34
  handlePressEnter,
35
- value,
36
  regenerateMessage,
37
  removeMessageById,
 
38
  } = useSendNextMessage();
39
 
40
  const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
@@ -52,33 +54,35 @@ const ChatContainer = () => {
52
  <Flex flex={1} vertical className={styles.messageContainer}>
53
  <div>
54
  <Spin spinning={loading}>
55
- {derivedMessages?.map((message, i) => {
56
- return (
57
- <MessageItem
58
- loading={
59
- message.role === MessageType.Assistant &&
60
- sendLoading &&
61
- derivedMessages.length - 1 === i
62
- }
63
- key={message.id}
64
- item={message}
65
- nickname={userInfo.nickname}
66
- avatar={userInfo.avatar}
67
- reference={buildMessageItemReference(
68
- {
69
- message: derivedMessages,
70
- reference: conversation.reference,
71
- },
72
- message,
73
- )}
74
- clickDocumentButton={clickDocumentButton}
75
- index={i}
76
- removeMessageById={removeMessageById}
77
- regenerateMessage={regenerateMessage}
78
- sendLoading={sendLoading}
79
- ></MessageItem>
80
- );
81
- })}
 
 
82
  </Spin>
83
  </div>
84
  <div ref={ref} />
 
19
  } from '@/hooks/chat-hooks';
20
  import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
21
  import { memo } from 'react';
22
+ import { ConversationContext } from '../context';
23
  import styles from './index.less';
24
 
25
  const ChatContainer = () => {
 
27
  const { data: conversation } = useFetchNextConversation();
28
 
29
  const {
30
+ value,
31
  ref,
32
  loading,
33
  sendLoading,
34
  derivedMessages,
35
  handleInputChange,
36
  handlePressEnter,
 
37
  regenerateMessage,
38
  removeMessageById,
39
+ redirectToNewConversation,
40
  } = useSendNextMessage();
41
 
42
  const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
 
54
  <Flex flex={1} vertical className={styles.messageContainer}>
55
  <div>
56
  <Spin spinning={loading}>
57
+ <ConversationContext.Provider value={redirectToNewConversation}>
58
+ {derivedMessages?.map((message, i) => {
59
+ return (
60
+ <MessageItem
61
+ loading={
62
+ message.role === MessageType.Assistant &&
63
+ sendLoading &&
64
+ derivedMessages.length - 1 === i
65
+ }
66
+ key={message.id}
67
+ item={message}
68
+ nickname={userInfo.nickname}
69
+ avatar={userInfo.avatar}
70
+ reference={buildMessageItemReference(
71
+ {
72
+ message: derivedMessages,
73
+ reference: conversation.reference,
74
+ },
75
+ message,
76
+ )}
77
+ clickDocumentButton={clickDocumentButton}
78
+ index={i}
79
+ removeMessageById={removeMessageById}
80
+ regenerateMessage={regenerateMessage}
81
+ sendLoading={sendLoading}
82
+ ></MessageItem>
83
+ );
84
+ })}
85
+ </ConversationContext.Provider>
86
  </Spin>
87
  </div>
88
  <div ref={ref} />
web/src/pages/chat/context.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import { createContext } from 'react';
2
+
3
+ export const ConversationContext = createContext<
4
+ null | ((isPlaying: boolean) => void)
5
+ >(null);
web/src/pages/chat/hooks.ts CHANGED
@@ -32,6 +32,7 @@ import {
32
  useCallback,
33
  useEffect,
34
  useMemo,
 
35
  useState,
36
  } from 'react';
37
  import { useSearchParams } from 'umi';
@@ -340,6 +341,17 @@ export const useSendNextMessage = () => {
340
  removeMessageById,
341
  removeMessagesAfterCurrentMessage,
342
  } = useSelectNextMessages();
 
 
 
 
 
 
 
 
 
 
 
343
 
344
  const sendMessage = useCallback(
345
  async ({
@@ -365,7 +377,9 @@ export const useSendNextMessage = () => {
365
  if (currentConversationId) {
366
  console.info('111');
367
  // new conversation
368
- handleClickConversation(currentConversationId);
 
 
369
  } else {
370
  console.info('222');
371
  // fetchConversation(conversationId);
@@ -373,6 +387,7 @@ export const useSendNextMessage = () => {
373
  }
374
  },
375
  [
 
376
  derivedMessages,
377
  conversationId,
378
  handleClickConversation,
@@ -390,6 +405,7 @@ export const useSendNextMessage = () => {
390
  const data = await setConversation(message.content);
391
  if (data.retcode === 0) {
392
  const id = data.data.id;
 
393
  sendMessage({
394
  message,
395
  currentConversationId: id,
@@ -463,6 +479,7 @@ export const useSendNextMessage = () => {
463
  ref,
464
  derivedMessages,
465
  removeMessageById,
 
466
  };
467
  };
468
 
 
32
  useCallback,
33
  useEffect,
34
  useMemo,
35
+ useRef,
36
  useState,
37
  } from 'react';
38
  import { useSearchParams } from 'umi';
 
341
  removeMessageById,
342
  removeMessagesAfterCurrentMessage,
343
  } = useSelectNextMessages();
344
+ const { data: dialog } = useFetchNextDialog();
345
+ const currentConversationIdRef = useRef<string>('');
346
+
347
+ const redirectToNewConversation = useCallback(
348
+ (isPlaying: boolean) => {
349
+ if (!conversationId && dialog?.prompt_config?.tts && !isPlaying) {
350
+ handleClickConversation(currentConversationIdRef.current);
351
+ }
352
+ },
353
+ [dialog, handleClickConversation, conversationId],
354
+ );
355
 
356
  const sendMessage = useCallback(
357
  async ({
 
377
  if (currentConversationId) {
378
  console.info('111');
379
  // new conversation
380
+ if (!dialog?.prompt_config?.tts) {
381
+ handleClickConversation(currentConversationId);
382
+ }
383
  } else {
384
  console.info('222');
385
  // fetchConversation(conversationId);
 
387
  }
388
  },
389
  [
390
+ dialog,
391
  derivedMessages,
392
  conversationId,
393
  handleClickConversation,
 
405
  const data = await setConversation(message.content);
406
  if (data.retcode === 0) {
407
  const id = data.data.id;
408
+ currentConversationIdRef.current = id;
409
  sendMessage({
410
  message,
411
  currentConversationId: id,
 
479
  ref,
480
  derivedMessages,
481
  removeMessageById,
482
+ redirectToNewConversation,
483
  };
484
  };
485