File size: 3,069 Bytes
7d8f5e6 d2e049e a7e962d d2e049e 7b381b0 a7e962d 809dc5c d2e049e 7d8f5e6 0086f8a 7d8f5e6 0086f8a 7d8f5e6 a7e962d 16e3fae a7e962d 809dc5c a7e962d 7b381b0 809dc5c 7b381b0 16e3fae a7e962d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
import { useDeleteMessage, useFeedback } from '@/hooks/chat-hooks';
import { useSetModalState } from '@/hooks/common-hooks';
import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks';
import { IFeedbackRequestBody } from '@/interfaces/request/chat';
import { getMessagePureId } from '@/utils/chat';
import { hexStringToUint8Array } from '@/utils/common-util';
import { SpeechPlayer } from 'openai-speech-stream-player';
import { useCallback, useEffect, useRef, useState } from 'react';
export const useSendFeedback = (messageId: string) => {
const { visible, hideModal, showModal } = useSetModalState();
const { feedback, loading } = useFeedback();
const onFeedbackOk = useCallback(
async (params: IFeedbackRequestBody) => {
const ret = await feedback({
...params,
messageId: getMessagePureId(messageId),
});
if (ret === 0) {
hideModal();
}
},
[feedback, hideModal, messageId],
);
return {
loading,
onFeedbackOk,
visible,
hideModal,
showModal,
};
};
export const useRemoveMessage = (
messageId: string,
removeMessageById?: IRemoveMessageById['removeMessageById'],
) => {
const { deleteMessage, loading } = useDeleteMessage();
const onRemoveMessage = useCallback(async () => {
const pureId = getMessagePureId(messageId);
if (pureId) {
const retcode = await deleteMessage(pureId);
if (retcode === 0) {
removeMessageById?.(messageId);
}
}
}, [deleteMessage, messageId, removeMessageById]);
return { onRemoveMessage, loading };
};
export const useSpeech = (content: string, audioBinary?: string) => {
const ref = useRef<HTMLAudioElement>(null);
const { read } = useSpeechWithSse();
const player = useRef<SpeechPlayer>();
const [isPlaying, setIsPlaying] = useState<boolean>(false);
const initialize = useCallback(async () => {
player.current = new SpeechPlayer({
audio: ref.current!,
onPlaying: () => {
setIsPlaying(true);
},
onPause: () => {
setIsPlaying(false);
},
onChunkEnd: () => {},
mimeType: 'audio/mpeg',
});
await player.current.init();
}, []);
const pause = useCallback(() => {
player.current?.pause();
}, []);
const speech = useCallback(async () => {
const response = await read({ text: content });
if (response) {
player?.current?.feedWithResponse(response);
}
}, [read, content]);
const handleRead = useCallback(async () => {
if (isPlaying) {
setIsPlaying(false);
pause();
} else {
setIsPlaying(true);
speech();
}
}, [setIsPlaying, speech, isPlaying, pause]);
useEffect(() => {
if (audioBinary) {
const units = hexStringToUint8Array(audioBinary);
if (units) {
try {
player.current?.feed(units);
} catch (error) {
console.warn(error);
}
}
}
}, [audioBinary]);
useEffect(() => {
initialize();
}, [initialize]);
return { ref, handleRead, isPlaying };
};
|