|
import endpoints from './endpoints'; |
|
import { useCallback } from 'react'; |
|
import { |
|
atom, |
|
selector, |
|
atomFamily, |
|
useSetRecoilState, |
|
useResetRecoilState, |
|
useRecoilCallback, |
|
} from 'recoil'; |
|
import buildTree from '~/utils/buildTree'; |
|
import getDefaultConversation from '~/utils/getDefaultConversation'; |
|
import submission from './submission.js'; |
|
|
|
const conversation = atom({ |
|
key: 'conversation', |
|
default: null, |
|
}); |
|
|
|
|
|
|
|
|
|
const messages = atom({ |
|
key: 'messages', |
|
default: [], |
|
}); |
|
|
|
const messagesTree = selector({ |
|
key: 'messagesTree', |
|
get: ({ get }) => { |
|
return buildTree(get(messages), false); |
|
}, |
|
}); |
|
|
|
const latestMessage = atom({ |
|
key: 'latestMessage', |
|
default: null, |
|
}); |
|
|
|
const messagesSiblingIdxFamily = atomFamily({ |
|
key: 'messagesSiblingIdx', |
|
default: 0, |
|
}); |
|
|
|
const useConversation = () => { |
|
const setConversation = useSetRecoilState(conversation); |
|
const setMessages = useSetRecoilState(messages); |
|
const setSubmission = useSetRecoilState(submission.submission); |
|
const resetLatestMessage = useResetRecoilState(latestMessage); |
|
|
|
const _switchToConversation = ( |
|
conversation, |
|
messages = null, |
|
preset = null, |
|
{ endpointsConfig = {}, prevConversation = {} }, |
|
) => { |
|
let { endpoint = null } = conversation; |
|
|
|
if (endpoint === null) { |
|
|
|
conversation = getDefaultConversation({ |
|
conversation, |
|
endpointsConfig, |
|
prevConversation, |
|
preset, |
|
}); |
|
} |
|
|
|
setConversation(conversation); |
|
setMessages(messages); |
|
setSubmission({}); |
|
resetLatestMessage(); |
|
}; |
|
|
|
const switchToConversation = useRecoilCallback( |
|
({ snapshot }) => |
|
async (_conversation, messages = null, preset = null) => { |
|
const prevConversation = await snapshot.getPromise(conversation); |
|
const endpointsConfig = await snapshot.getPromise(endpoints.endpointsConfig); |
|
_switchToConversation(_conversation, messages, preset, { |
|
endpointsConfig, |
|
prevConversation, |
|
}); |
|
}, |
|
[], |
|
); |
|
|
|
const newConversation = useCallback( |
|
(template = {}, preset) => { |
|
switchToConversation( |
|
{ |
|
conversationId: 'new', |
|
title: 'New Chat', |
|
...template, |
|
}, |
|
[], |
|
preset, |
|
); |
|
}, |
|
[switchToConversation], |
|
); |
|
|
|
const searchPlaceholderConversation = () => { |
|
switchToConversation( |
|
{ |
|
conversationId: 'search', |
|
title: 'Search', |
|
}, |
|
[], |
|
); |
|
}; |
|
|
|
return { |
|
_switchToConversation, |
|
newConversation, |
|
switchToConversation, |
|
searchPlaceholderConversation, |
|
}; |
|
}; |
|
|
|
export default { |
|
conversation, |
|
messages, |
|
messagesTree, |
|
latestMessage, |
|
messagesSiblingIdxFamily, |
|
useConversation, |
|
}; |
|
|