mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-22 03:10:15 +01:00
feat: new endpoint-style structure in client side
NOT FINISHED. model menu and icon and send message not work.
This commit is contained in:
parent
dd825dc6d4
commit
c53778e7c1
10 changed files with 172 additions and 243 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState, useRef } from 'react';
|
||||
import { useRecoilState, useResetRecoilState, useSetRecoilState } from 'recoil';
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||
|
||||
import RenameButton from './RenameButton';
|
||||
import DeleteButton from './DeleteButton';
|
||||
|
|
@ -10,9 +10,7 @@ import store from '~/store';
|
|||
|
||||
export default function Conversation({ conversation, retainView }) {
|
||||
const [currentConversation, setCurrentConversation] = useRecoilState(store.conversation);
|
||||
const setMessages = useSetRecoilState(store.messages);
|
||||
const setSubmission = useSetRecoilState(store.submission);
|
||||
const resetLatestMessage = useResetRecoilState(store.latestMessage);
|
||||
|
||||
const { refreshConversations } = store.useConversations();
|
||||
const { switchToConversation } = store.useConversation();
|
||||
|
|
@ -21,33 +19,10 @@ export default function Conversation({ conversation, retainView }) {
|
|||
const [titleInput, setTitleInput] = useState(title);
|
||||
const inputRef = useRef(null);
|
||||
|
||||
const {
|
||||
model,
|
||||
parentMessageId,
|
||||
conversationId,
|
||||
title,
|
||||
chatGptLabel = null,
|
||||
promptPrefix = null,
|
||||
jailbreakConversationId,
|
||||
conversationSignature,
|
||||
clientId,
|
||||
invocationId,
|
||||
toneStyle
|
||||
} = conversation;
|
||||
const { conversationId, title } = conversation;
|
||||
|
||||
const rename = manualSWR(`/api/convos/update`, 'post');
|
||||
|
||||
const bingData = conversationSignature
|
||||
? {
|
||||
jailbreakConversationId: jailbreakConversationId,
|
||||
conversationSignature: conversationSignature,
|
||||
parentMessageId: parentMessageId || null,
|
||||
clientId: clientId,
|
||||
invocationId: invocationId,
|
||||
toneStyle: toneStyle
|
||||
}
|
||||
: null;
|
||||
|
||||
const clickHandler = async () => {
|
||||
if (currentConversation?.conversationId === conversationId) {
|
||||
return;
|
||||
|
|
@ -58,64 +33,6 @@ export default function Conversation({ conversation, retainView }) {
|
|||
|
||||
// set conversation to the new conversation
|
||||
switchToConversation(conversation);
|
||||
|
||||
// if (!stopStream) {
|
||||
// dispatch(setStopStream(true));
|
||||
// dispatch(setSubmission({}));
|
||||
// }
|
||||
// dispatch(setEmptyMessage());
|
||||
|
||||
// const convo = { title, error: false, conversationId: id, chatGptLabel, promptPrefix };
|
||||
|
||||
// if (bingData) {
|
||||
// const {
|
||||
// parentMessageId,
|
||||
// conversationSignature,
|
||||
// jailbreakConversationId,
|
||||
// clientId,
|
||||
// invocationId,
|
||||
// toneStyle
|
||||
// } = bingData;
|
||||
// dispatch(
|
||||
// setConversation({
|
||||
// ...convo,
|
||||
// parentMessageId,
|
||||
// jailbreakConversationId,
|
||||
// conversationSignature,
|
||||
// clientId,
|
||||
// invocationId,
|
||||
// toneStyle,
|
||||
// latestMessage: null
|
||||
// })
|
||||
// );
|
||||
// } else {
|
||||
// dispatch(
|
||||
// setConversation({
|
||||
// ...convo,
|
||||
// parentMessageId,
|
||||
// jailbreakConversationId: null,
|
||||
// conversationSignature: null,
|
||||
// clientId: null,
|
||||
// invocationId: null,
|
||||
// toneStyle: null,
|
||||
// latestMessage: null
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
// const data = await trigger();
|
||||
|
||||
// if (chatGptLabel) {
|
||||
// dispatch(setModel('chatgptCustom'));
|
||||
// dispatch(setCustomModel(chatGptLabel.toLowerCase()));
|
||||
// } else {
|
||||
// dispatch(setModel(model));
|
||||
// dispatch(setCustomModel(null));
|
||||
// }
|
||||
|
||||
// dispatch(setMessages(data));
|
||||
// dispatch(setCustomGpt(convo));
|
||||
// dispatch(setText(''));
|
||||
// dispatch(setStopStream(false));
|
||||
};
|
||||
|
||||
const renameHandler = e => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useRecoilValue, useRecoilState } from 'recoil';
|
|||
import SubmitButton from './SubmitButton';
|
||||
import AdjustToneButton from './AdjustToneButton';
|
||||
import BingStyles from './BingStyles';
|
||||
import ModelMenu from './Models/ModelMenu';
|
||||
// import ModelMenu from './Models/ModelMenu';
|
||||
import Footer from './Footer';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
import RegenerateIcon from '../svg/RegenerateIcon';
|
||||
|
|
@ -167,7 +167,7 @@ export default function TextChat({ isSearchView = false }) {
|
|||
disabled ? 'dark:bg-gray-900' : 'dark:bg-gray-700'
|
||||
} dark:text-white dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] md:py-3 md:pl-4`}
|
||||
>
|
||||
<ModelMenu />
|
||||
{/* <ModelMenu /> */}
|
||||
<TextareaAutosize
|
||||
tabIndex="0"
|
||||
autoFocus
|
||||
|
|
|
|||
|
|
@ -2,21 +2,22 @@ import React from 'react';
|
|||
// import Clipboard from '../svg/Clipboard';
|
||||
import EditIcon from '../svg/EditIcon';
|
||||
|
||||
export default function HoverButtons({ visible, onClick, model }) {
|
||||
const isBing = model === 'bingai';
|
||||
const enabled = !isBing;
|
||||
export default function HoverButtons({ visible, onClick, endpoint }) {
|
||||
const enabled = endpoint in ['azureOpenAI', 'openAI', 'chatGPTBrowser'];
|
||||
|
||||
return (
|
||||
<div className="visible mt-2 flex justify-center gap-3 self-end text-gray-400 md:gap-4 lg:absolute lg:top-0 lg:right-0 lg:mt-0 lg:translate-x-full lg:gap-1 lg:self-center lg:pl-2">
|
||||
{(visible&&enabled)?(
|
||||
{visible && enabled ? (
|
||||
<>
|
||||
<button className="resubmit-edit-button rounded-md p-1 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:invisible md:group-hover:visible"
|
||||
onClick={onClick}>
|
||||
<button
|
||||
className="resubmit-edit-button rounded-md p-1 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:invisible md:group-hover:visible"
|
||||
onClick={onClick}
|
||||
>
|
||||
{/* <button className="rounded-md p-1 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400"> */}
|
||||
<EditIcon />
|
||||
</button>
|
||||
</>
|
||||
):null}
|
||||
) : null}
|
||||
{/* <button className="rounded-md p-1 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400">
|
||||
<Clipboard />
|
||||
</button> */}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import MultiMessage from './MultiMessage';
|
|||
import HoverButtons from './HoverButtons';
|
||||
import SiblingSwitch from './SiblingSwitch';
|
||||
import { fetchById } from '~/utils/fetchers';
|
||||
import { getIconOfModel } from '~/utils';
|
||||
import { getIconOfAi } from '~/utils';
|
||||
import { useMessageHandler } from '~/utils/handleSubmit';
|
||||
|
||||
import store from '~/store';
|
||||
|
|
@ -23,32 +23,15 @@ export default function Message({
|
|||
}) {
|
||||
const isSubmitting = useRecoilValue(store.isSubmitting);
|
||||
const setLatestMessage = useSetRecoilState(store.latestMessage);
|
||||
const { model, chatGptLabel, promptPrefix } = conversation;
|
||||
// const { model, chatGptLabel, promptPrefix } = conversation;
|
||||
const [abortScroll, setAbort] = useState(false);
|
||||
const {
|
||||
sender,
|
||||
text,
|
||||
searchResult,
|
||||
isCreatedByUser,
|
||||
error,
|
||||
submitting,
|
||||
model: messageModel,
|
||||
chatGptLabel: messageChatGptLabel,
|
||||
searchResult: isSearchResult
|
||||
} = message;
|
||||
const { text, searchResult, isCreatedByUser, error, submitting } = message;
|
||||
const textEditor = useRef(null);
|
||||
const last = !message?.children?.length;
|
||||
const edit = message.messageId == currentEditId;
|
||||
const { ask } = useMessageHandler();
|
||||
const { switchToConversation } = store.useConversation();
|
||||
const blinker = submitting && isSubmitting;
|
||||
const generateCursor = useCallback(() => {
|
||||
if (!blinker) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return <span className="result-streaming">█</span>;
|
||||
}, [blinker]);
|
||||
|
||||
useEffect(() => {
|
||||
if (blinker && !abortScroll) {
|
||||
|
|
@ -77,14 +60,9 @@ export default function Message({
|
|||
'w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 bg-white dark:text-gray-100 group dark:bg-gray-800'
|
||||
};
|
||||
|
||||
const icon = getIconOfModel({
|
||||
sender,
|
||||
isCreatedByUser,
|
||||
model: isSearchResult ? messageModel : model,
|
||||
searchResult,
|
||||
chatGptLabel: isSearchResult ? messageChatGptLabel : chatGptLabel,
|
||||
promptPrefix,
|
||||
error
|
||||
const icon = getIconOfAi({
|
||||
...conversation,
|
||||
...message
|
||||
});
|
||||
|
||||
if (!isCreatedByUser)
|
||||
|
|
@ -199,7 +177,7 @@ export default function Message({
|
|||
)}
|
||||
</div>
|
||||
<HoverButtons
|
||||
model={model}
|
||||
endpoint={conversation?.endpoint}
|
||||
visible={!error && isCreatedByUser && !edit && !searchResult}
|
||||
onClick={() => enterEdit()}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
import React, { useRef, useEffect, useState } from 'react';
|
||||
|
||||
const MessageBar = ({ children, dynamicProps, handleWheel, clickSearchResult }) => {
|
||||
const ref = useRef(null);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
setIsVisible(true);
|
||||
observer.unobserve(ref.current);
|
||||
}
|
||||
},
|
||||
{ threshold: 0.1 }
|
||||
);
|
||||
|
||||
observer.observe(ref.current);
|
||||
|
||||
return () => {
|
||||
observer.unobserve(ref.current);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
{...dynamicProps}
|
||||
onWheel={handleWheel}
|
||||
// onClick={clickSearchResult}
|
||||
|
||||
ref={ref}
|
||||
>
|
||||
{isVisible ? children : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MessageBar;
|
||||
|
|
@ -20,10 +20,10 @@ export default function Messages({ isSearchView = false }) {
|
|||
const _messagesTree = isSearchView ? searchResultMessagesTree : messagesTree;
|
||||
|
||||
const conversation = useRecoilValue(store.conversation) || {};
|
||||
const { conversationId, model, chatGptLabel, toneStyle } = conversation;
|
||||
const { conversationId, endpoint } = conversation;
|
||||
|
||||
const models = useRecoilValue(store.models) || [];
|
||||
const modelName = models.find(element => element.model == model)?.name;
|
||||
// const models = useRecoilValue(store.models) || [];
|
||||
// const modelName = models.find(element => element.model == model)?.name;
|
||||
|
||||
const searchQuery = useRecoilValue(store.searchQuery);
|
||||
|
||||
|
|
@ -82,9 +82,22 @@ export default function Messages({ isSearchView = false }) {
|
|||
const getConversationTitle = () => {
|
||||
if (isSearchView) return `Search: ${searchQuery}`;
|
||||
else {
|
||||
let _title = `Model: ${modelName}`;
|
||||
if (chatGptLabel) _title += ` of ${chatGptLabel}`;
|
||||
if (toneStyle) _title += ` (${toneStyle})`;
|
||||
let _title = `${endpoint}`;
|
||||
|
||||
if (endpoint === 'azureOpenAI' || endpoint === 'openAI') {
|
||||
const { chatGptLabel, model } = conversation;
|
||||
if (model) _title += `: ${model}`;
|
||||
if (chatGptLabel) _title += ` as ${chatGptLabel}`;
|
||||
} else if (endpoint === 'bingAI') {
|
||||
const { jailbreak, toneStyle } = conversation;
|
||||
if (toneStyle) _title += `: ${toneStyle}`;
|
||||
if (jailbreak) _title += ` as Sydney`;
|
||||
} else if (endpoint === 'chatGPTBrowser') {
|
||||
const { model } = conversation;
|
||||
if (model) _title += `: ${model}`;
|
||||
} else if (endpoint === null) {
|
||||
null;
|
||||
}
|
||||
return _title;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue