ragflow / web /src /pages /chat /shared-hooks.ts
zxsipola123456's picture
Upload 769 files
ab2ded1 verified
raw
history blame
5.97 kB
import { MessageType } from '@/constants/chat';
import {
useCreateSharedConversation,
useFetchSharedConversation,
} from '@/hooks/chat-hooks';
import { useSendMessageWithSse } from '@/hooks/logic-hooks';
import { useOneNamespaceEffectsLoading } from '@/hooks/store-hooks';
import { IAnswer } from '@/interfaces/database/chat';
import api from '@/utils/api';
import omit from 'lodash/omit';
import trim from 'lodash/trim';
import {
Dispatch,
SetStateAction,
useCallback,
useEffect,
useState,
} from 'react';
import { useSearchParams } from 'umi';
import { v4 as uuid } from 'uuid';
import { useHandleMessageInputChange, useScrollToBottom } from './hooks';
import { IClientConversation, IMessage } from './interface';
export const useCreateSharedConversationOnMount = () => {
const [currentQueryParameters] = useSearchParams();
const [conversationId, setConversationId] = useState('');
const createConversation = useCreateSharedConversation();
const sharedId = currentQueryParameters.get('shared_id');
const userId = currentQueryParameters.get('user_id');
const setConversation = useCallback(async () => {
console.info(sharedId);
if (sharedId) {
const data = await createConversation(userId ?? undefined);
const id = data.data?.id;
if (id) {
setConversationId(id);
}
}
}, [createConversation, sharedId, userId]);
useEffect(() => {
setConversation();
}, [setConversation]);
return { conversationId };
};
export const useSelectCurrentSharedConversation = (conversationId: string) => {
const [currentConversation, setCurrentConversation] =
useState<IClientConversation>({} as IClientConversation);
const fetchConversation = useFetchSharedConversation();
const loading = useOneNamespaceEffectsLoading('chatModel', [
'getExternalConversation',
]);
const ref = useScrollToBottom(currentConversation);
const addNewestConversation = useCallback((message: string) => {
setCurrentConversation((pre) => {
return {
...pre,
message: [
...(pre.message ?? []),
{
role: MessageType.User,
content: message,
id: uuid(),
} as IMessage,
{
role: MessageType.Assistant,
content: '',
id: uuid(),
reference: [],
} as IMessage,
],
};
});
}, []);
const addNewestAnswer = useCallback((answer: IAnswer) => {
setCurrentConversation((pre) => {
const latestMessage = pre.message?.at(-1);
if (latestMessage) {
return {
...pre,
message: [
...pre.message.slice(0, -1),
{
...latestMessage,
content: answer.answer,
reference: answer.reference,
} as IMessage,
],
};
}
return pre;
});
}, []);
const removeLatestMessage = useCallback(() => {
setCurrentConversation((pre) => {
const nextMessages = pre.message.slice(0, -2);
return {
...pre,
message: nextMessages,
};
});
}, []);
const fetchConversationOnMount = useCallback(async () => {
if (conversationId) {
const data = await fetchConversation(conversationId);
if (data.retcode === 0) {
setCurrentConversation(data.data);
}
}
}, [conversationId, fetchConversation]);
useEffect(() => {
fetchConversationOnMount();
}, [fetchConversationOnMount]);
return {
currentConversation,
addNewestConversation,
removeLatestMessage,
loading,
ref,
setCurrentConversation,
addNewestAnswer,
};
};
export const useSendButtonDisabled = (value: string) => {
return trim(value) === '';
};
export const useSendSharedMessage = (
conversation: IClientConversation,
addNewestConversation: (message: string) => void,
removeLatestMessage: () => void,
setCurrentConversation: Dispatch<SetStateAction<IClientConversation>>,
addNewestAnswer: (answer: IAnswer) => void,
) => {
const conversationId = conversation.id;
const setConversation = useCreateSharedConversation();
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
const { send, answer, done } = useSendMessageWithSse(
api.completeExternalConversation,
);
const sendMessage = useCallback(
async (message: string, id?: string) => {
const res = await send({
conversation_id: id ?? conversationId,
quote: false,
messages: [
...(conversation?.message ?? []).map((x: IMessage) => omit(x, 'id')),
{
role: MessageType.User,
content: message,
},
],
});
if (res && (res?.response.status !== 200 || res?.data?.retcode !== 0)) {
// cancel loading
setValue(message);
removeLatestMessage();
}
},
[
conversationId,
conversation?.message,
// fetchConversation,
removeLatestMessage,
setValue,
send,
// setCurrentConversation,
],
);
const handleSendMessage = useCallback(
async (message: string) => {
if (conversationId !== '') {
sendMessage(message);
} else {
const data = await setConversation('user id');
if (data.retcode === 0) {
const id = data.data.id;
sendMessage(message, id);
}
}
},
[conversationId, setConversation, sendMessage],
);
useEffect(() => {
if (answer.answer) {
addNewestAnswer(answer);
}
}, [answer, addNewestAnswer]);
const handlePressEnter = useCallback(() => {
if (trim(value) === '') return;
if (done) {
setValue('');
addNewestConversation(value);
handleSendMessage(value.trim());
}
}, [addNewestConversation, done, handleSendMessage, setValue, value]);
return {
handlePressEnter,
handleInputChange,
value,
loading: !done,
};
};