fix: missing icon of search result

feat: use search result message as single list
This commit is contained in:
Wentao Lyu 2023-03-29 02:29:15 +08:00
parent dc743df255
commit aa26eea8c5
6 changed files with 102 additions and 44 deletions

View file

@ -42,7 +42,7 @@ router.get('/', async function (req, res) {
}, },
true true
) )
).hits.map((message) => { ).hits.map(message => {
const { _formatted, ...rest } = message; const { _formatted, ...rest } = message;
return { return {
...rest, ...rest,
@ -64,7 +64,9 @@ router.get('/', async function (req, res) {
message.conversationId = cleanUpPrimaryKeyValue(message.conversationId); message.conversationId = cleanUpPrimaryKeyValue(message.conversationId);
} }
if (result.convoMap[message.conversationId] && !message.error) { if (result.convoMap[message.conversationId] && !message.error) {
message = { ...message, title: result.convoMap[message.conversationId].title }; const convo = result.convoMap[message.conversationId];
const { title, chatGptLabel, model } = convo;
message = { ...message, ...{ title, chatGptLabel, model } };
activeMessages.push(message); activeMessages.push(message);
} }
} }
@ -91,12 +93,12 @@ router.get('/clear', async function (req, res) {
router.get('/test', async function (req, res) { router.get('/test', async function (req, res) {
const { q } = req.query; const { q } = req.query;
const messages = ( const messages = (await Message.meiliSearch(q, { attributesToHighlight: ['text'] }, true)).hits.map(
await Message.meiliSearch(q, { attributesToHighlight: ['text'] }, true) message => {
).hits.map((message) => {
const { _formatted, ...rest } = message; const { _formatted, ...rest } = message;
return { ...rest, searchResult: true, text: _formatted.text }; return { ...rest, searchResult: true, text: _formatted.text };
}); }
);
res.send(messages); res.send(messages);
}); });

View file

@ -25,7 +25,17 @@ export default function Message({
const setLatestMessage = useSetRecoilState(store.latestMessage); const setLatestMessage = useSetRecoilState(store.latestMessage);
const { model, chatGptLabel, promptPrefix } = conversation; const { model, chatGptLabel, promptPrefix } = conversation;
const [abortScroll, setAbort] = useState(false); const [abortScroll, setAbort] = useState(false);
const { sender, text, searchResult, isCreatedByUser, error, submitting } = message; const {
sender,
text,
searchResult,
isCreatedByUser,
error,
submitting,
model: messageModel,
chatGptLabel: messageChatGptLabel,
searchResult: isSearchResult
} = message;
const textEditor = useRef(null); const textEditor = useRef(null);
const last = !message?.children?.length; const last = !message?.children?.length;
const edit = message.messageId == currentEditId; const edit = message.messageId == currentEditId;
@ -70,9 +80,9 @@ export default function Message({
const icon = getIconOfModel({ const icon = getIconOfModel({
sender, sender,
isCreatedByUser, isCreatedByUser,
model, model: isSearchResult ? messageModel : model,
searchResult, searchResult,
chatGptLabel, chatGptLabel: isSearchResult ? messageChatGptLabel : chatGptLabel,
promptPrefix, promptPrefix,
error error
}); });

View file

@ -6,7 +6,8 @@ export default function MultiMessage({
messagesTree, messagesTree,
scrollToBottom, scrollToBottom,
currentEditId, currentEditId,
setCurrentEditId setCurrentEditId,
isSearchView
}) { }) {
const [siblingIdx, setSiblingIdx] = useState(0); const [siblingIdx, setSiblingIdx] = useState(0);
@ -30,6 +31,26 @@ export default function MultiMessage({
} }
const message = messagesTree[messagesTree.length - siblingIdx - 1]; const message = messagesTree[messagesTree.length - siblingIdx - 1];
if (isSearchView)
return (
<>
{messagesTree
? messagesTree.map(message => (
<Message
key={message.messageId}
conversation={conversation}
message={message}
scrollToBottom={scrollToBottom}
currentEditId={currentEditId}
setCurrentEditId={null}
siblingIdx={1}
siblingCount={1}
setSiblingIdx={null}
/>
))
: null}
</>
);
return ( return (
<Message <Message
key={message.messageId} key={message.messageId}

View file

@ -107,6 +107,7 @@ export default function Messages({ isSearchView = false }) {
scrollToBottom={scrollToBottom} scrollToBottom={scrollToBottom}
currentEditId={currentEditId} currentEditId={currentEditId}
setCurrentEditId={setCurrentEditId} setCurrentEditId={setCurrentEditId}
isSearchView={isSearchView}
/> />
<CSSTransition <CSSTransition
in={showScrollButton} in={showScrollButton}

View file

@ -9,6 +9,9 @@ export default function buildTree(messages, groupAll = false) {
let messageMap = {}; let messageMap = {};
let rootMessages = []; let rootMessages = [];
if (groupAll) {
return messages.map((m, idx) => ({ ...m, bg: idx % 2 === 0 ? even : odd }));
}
if (!groupAll) { if (!groupAll) {
// Traverse the messages array and store each element in messageMap. // Traverse the messages array and store each element in messageMap.
messages.forEach(message => { messages.forEach(message => {
@ -22,18 +25,18 @@ export default function buildTree(messages, groupAll = false) {
return rootMessages; return rootMessages;
} }
// Group all messages into one tree // // Group all messages into one tree
let parentId = null; // let parentId = null;
messages.forEach((message, i) => { // messages.forEach((message, i) => {
messageMap[message.messageId] = { ...message, bg: i % 2 === 0 ? even : odd, children: [] }; // messageMap[message.messageId] = { ...message, bg: i % 2 === 0 ? even : odd, children: [] };
const currentMessage = messageMap[message.messageId]; // const currentMessage = messageMap[message.messageId];
const parentMessage = messageMap[parentId]; // const parentMessage = messageMap[parentId];
if (parentMessage) parentMessage.children.push(currentMessage); // if (parentMessage) parentMessage.children.push(currentMessage);
else rootMessages.push(currentMessage); // else rootMessages.push(currentMessage);
parentId = message.messageId; // parentId = message.messageId;
}); // });
return rootMessages; // return rootMessages;
// Group all messages by conversation, doesn't look great // Group all messages by conversation, doesn't look great
// Traverse the messages array and store each element in messageMap. // Traverse the messages array and store each element in messageMap.

View file

@ -38,40 +38,55 @@ export const languages = [
'pascal' 'pascal'
]; ];
export const getIconOfModel = ({ size=30, sender, isCreatedByUser, searchResult, model, chatGptLabel, error, ...props }) => { export const getIconOfModel = ({
// 'ai' is used as 'model' is not accurate for search results size = 30,
let ai = searchResult ? sender : model; sender,
isCreatedByUser,
searchResult,
model,
chatGptLabel,
error,
...props
}) => {
const { button } = props; const { button } = props;
const bgColors = { const bgColors = {
chatgpt: `rgb(16, 163, 127${ button ? ', 0.75' : ''})`, chatgpt: `rgb(16, 163, 127${button ? ', 0.75' : ''})`,
chatgptBrowser: `rgb(25, 207, 207${ button ? ', 0.75' : ''})`, chatgptBrowser: `rgb(25, 207, 207${button ? ', 0.75' : ''})`,
bingai: 'transparent', bingai: 'transparent',
sydney: 'radial-gradient(circle at 90% 110%, #F0F0FA, #D0E0F9)', sydney: 'radial-gradient(circle at 90% 110%, #F0F0FA, #D0E0F9)',
chatgptCustom: `rgb(0, 163, 255${ button ? ', 0.75' : ''})`, chatgptCustom: `rgb(0, 163, 255${button ? ', 0.75' : ''})`
}; };
if (isCreatedByUser) if (isCreatedByUser)
return ( return (
<div <div
title='User' title="User"
style={{ background: 'radial-gradient(circle at 90% 110%, rgb(1 43 128), rgb(17, 139, 161))', color: 'white', fontSize: 12, width: size, height: size }} style={{
background: 'radial-gradient(circle at 90% 110%, rgb(1 43 128), rgb(17, 139, 161))',
color: 'white',
fontSize: 12,
width: size,
height: size
}}
className={`relative flex items-center justify-center rounded-sm text-white ` + props?.className} className={`relative flex items-center justify-center rounded-sm text-white ` + props?.className}
> >
User User
</div> </div>
) );
else if (!isCreatedByUser) { else if (!isCreatedByUser) {
// TODO: use model from convo, rather than submit // TODO: use model from convo, rather than submit
// const { model, chatGptLabel, promptPrefix } = convo; // const { model, chatGptLabel, promptPrefix } = convo;
let background = bgColors[ai]; let background = bgColors[model];
const isBing = ai === 'bingai' || ai === 'sydney'; const isBing = model === 'bingai' || model === 'sydney';
return ( return (
<div <div
title={chatGptLabel || ai} title={chatGptLabel || model}
style={ style={{
{ background: background || 'radial-gradient(circle at 90% 110%, #F0F0FA, #D0E0F9)', width: size, height: size } background: background || 'radial-gradient(circle at 90% 110%, #F0F0FA, #D0E0F9)',
} width: size,
height: size
}}
className={`relative flex items-center justify-center rounded-sm text-white ` + props?.className} className={`relative flex items-center justify-center rounded-sm text-white ` + props?.className}
> >
{isBing ? <BingIcon size={size * 0.7} /> : <GPTIcon size={size * 0.7} />} {isBing ? <BingIcon size={size * 0.7} /> : <GPTIcon size={size * 0.7} />}
@ -85,11 +100,17 @@ export const getIconOfModel = ({ size=30, sender, isCreatedByUser, searchResult,
} else } else
return ( return (
<div <div
title='User' title="User"
style={{ background: 'radial-gradient(circle at 90% 110%, rgb(1 43 128), rgb(17, 139, 161))', color: 'white', fontSize: 12, width: size, height: size }} style={{
background: 'radial-gradient(circle at 90% 110%, rgb(1 43 128), rgb(17, 139, 161))',
color: 'white',
fontSize: 12,
width: size,
height: size
}}
className={`relative flex items-center justify-center rounded-sm p-1 text-white ` + props?.className} className={`relative flex items-center justify-center rounded-sm p-1 text-white ` + props?.className}
> >
{chatGptLabel} {chatGptLabel}
</div> </div>
) );
} };