選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

shared-hooks.ts 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import { MessageType, SharedFrom } from '@/constants/chat';
  2. import {
  3. useCreateNextSharedConversation,
  4. useFetchNextSharedConversation,
  5. } from '@/hooks/chat-hooks';
  6. import {
  7. useSelectDerivedMessages,
  8. useSendMessageWithSse,
  9. } from '@/hooks/logic-hooks';
  10. import { Message } from '@/interfaces/database/chat';
  11. import api from '@/utils/api';
  12. import trim from 'lodash/trim';
  13. import { useCallback, useEffect, useState } from 'react';
  14. import { useSearchParams } from 'umi';
  15. import { v4 as uuid } from 'uuid';
  16. import { useHandleMessageInputChange } from './hooks';
  17. export const useCreateSharedConversationOnMount = () => {
  18. const [currentQueryParameters] = useSearchParams();
  19. const [conversationId, setConversationId] = useState('');
  20. const { createSharedConversation: createConversation } =
  21. useCreateNextSharedConversation();
  22. const sharedId = currentQueryParameters.get('shared_id');
  23. const userId = currentQueryParameters.get('user_id');
  24. const setConversation = useCallback(async () => {
  25. if (sharedId) {
  26. const data = await createConversation(userId ?? undefined);
  27. const id = data.data?.id;
  28. if (id) {
  29. setConversationId(id);
  30. }
  31. }
  32. }, [createConversation, sharedId, userId]);
  33. useEffect(() => {
  34. setConversation();
  35. }, [setConversation]);
  36. return { conversationId };
  37. };
  38. export const useSelectNextSharedMessages = (conversationId: string) => {
  39. const { data, loading } = useFetchNextSharedConversation(conversationId);
  40. const {
  41. derivedMessages,
  42. ref,
  43. setDerivedMessages,
  44. addNewestAnswer,
  45. addNewestQuestion,
  46. removeLatestMessage,
  47. } = useSelectDerivedMessages();
  48. useEffect(() => {
  49. setDerivedMessages(data?.data?.message);
  50. }, [setDerivedMessages, data]);
  51. return {
  52. derivedMessages,
  53. addNewestAnswer,
  54. addNewestQuestion,
  55. removeLatestMessage,
  56. loading,
  57. ref,
  58. setDerivedMessages,
  59. };
  60. };
  61. export const useSendButtonDisabled = (value: string) => {
  62. return trim(value) === '';
  63. };
  64. export const useSendSharedMessage = (conversationId: string) => {
  65. const { createSharedConversation: setConversation } =
  66. useCreateNextSharedConversation();
  67. const { handleInputChange, value, setValue } = useHandleMessageInputChange();
  68. const { send, answer, done } = useSendMessageWithSse(
  69. api.completeExternalConversation,
  70. );
  71. const {
  72. derivedMessages,
  73. ref,
  74. removeLatestMessage,
  75. addNewestAnswer,
  76. addNewestQuestion,
  77. loading,
  78. } = useSelectNextSharedMessages(conversationId);
  79. const sendMessage = useCallback(
  80. async (message: Message, id?: string) => {
  81. const res = await send({
  82. conversation_id: id ?? conversationId,
  83. quote: false,
  84. messages: [...(derivedMessages ?? []), message],
  85. });
  86. if (res && (res?.response.status !== 200 || res?.data?.code !== 0)) {
  87. // cancel loading
  88. setValue(message.content);
  89. removeLatestMessage();
  90. }
  91. },
  92. [conversationId, derivedMessages, removeLatestMessage, setValue, send],
  93. );
  94. const handleSendMessage = useCallback(
  95. async (message: Message) => {
  96. if (conversationId !== '') {
  97. sendMessage(message);
  98. } else {
  99. const data = await setConversation('user id');
  100. if (data.code === 0) {
  101. const id = data.data.id;
  102. sendMessage(message, id);
  103. }
  104. }
  105. },
  106. [conversationId, setConversation, sendMessage],
  107. );
  108. useEffect(() => {
  109. if (answer.answer) {
  110. addNewestAnswer(answer);
  111. }
  112. }, [answer, addNewestAnswer]);
  113. const handlePressEnter = useCallback(
  114. (documentIds: string[]) => {
  115. if (trim(value) === '') return;
  116. const id = uuid();
  117. if (done) {
  118. setValue('');
  119. addNewestQuestion({
  120. content: value,
  121. doc_ids: documentIds,
  122. id,
  123. role: MessageType.User,
  124. });
  125. handleSendMessage({
  126. content: value.trim(),
  127. id,
  128. role: MessageType.User,
  129. });
  130. }
  131. },
  132. [addNewestQuestion, done, handleSendMessage, setValue, value],
  133. );
  134. return {
  135. handlePressEnter,
  136. handleInputChange,
  137. value,
  138. sendLoading: !done,
  139. ref,
  140. loading,
  141. derivedMessages,
  142. };
  143. };
  144. export const useGetSharedChatSearchParams = () => {
  145. const [searchParams] = useSearchParams();
  146. return {
  147. from: searchParams.get('from') as SharedFrom,
  148. sharedId: searchParams.get('shared_id'),
  149. };
  150. };