mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 05:12:39 +00:00
perf: guide modules
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<svg width="32" height="32" viewBox="0 0 1041 1348" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="1041" height="1348" viewBox="0 0 1041 1348" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M340.837 0.33933L681.068 0.338989V0.455643C684.032 0.378397 686.999 0.339702 689.967 0.339702C735.961 0.3397 781.504 9.62899 823.997 27.6772C866.49 45.7254 905.099 72.1791 937.622 105.528C970.144 138.877 995.942 178.467 1013.54 222.04C1031.14 265.612 1040.2 312.312 1040.2 359.474L340.836 359.474L340.836 1347.84C296.157 1347.84 251.914 1338.55 210.636 1320.49C169.357 1302.43 131.85 1275.95 100.257 1242.58C68.6636 1209.21 43.6023 1169.59 26.5041 1125.99C11.3834 1087.43 2.75216 1046.42 0.957956 1004.81H0.605869L0.605897 368.098H0.70363C0.105752 341.831 2.23741 315.443 7.14306 289.411C20.2709 219.745 52.6748 155.754 100.257 105.528C147.839 55.3017 208.462 21.0975 274.461 7.24017C296.426 2.62833 318.657 0.339101 340.837 0.33933Z" fill="url(#paint0_linear_1172_228)"/>
|
||||
<path d="M633.639 904.645H513.029V576.37H635.422V576.377C678.161 576.607 720.454 585.093 759.951 601.37C799.997 617.874 836.384 642.064 867.033 672.559C897.683 703.054 921.996 739.257 938.583 779.101C955.171 818.944 963.709 861.648 963.709 904.775H633.639V904.645Z" fill="url(#paint1_linear_1172_228)"/>
|
||||
<defs>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -8,8 +8,8 @@ const Avatar = ({ w = '30px', ...props }: ImageProps) => {
|
||||
<Image
|
||||
fallbackSrc={LOGO_ICON}
|
||||
fallbackStrategy={'onError'}
|
||||
borderRadius={'50%'}
|
||||
objectFit={'cover'}
|
||||
borderRadius={'md'}
|
||||
objectFit={'contain'}
|
||||
alt=""
|
||||
w={w}
|
||||
h={w}
|
||||
|
@@ -25,7 +25,7 @@ import {
|
||||
} from '@/utils/tools';
|
||||
import { Box, Card, Flex, Input, Textarea, Button, useTheme, BoxProps } from '@chakra-ui/react';
|
||||
import { feConfigs } from '@/store/static';
|
||||
import { EventNameEnum } from '../Markdown/constant';
|
||||
import { event } from '@/utils/plugin/eventbus';
|
||||
|
||||
import { adaptChatItem_openAI } from '@/utils/plugin/openai';
|
||||
import { useMarkdown } from '@/hooks/useMarkdown';
|
||||
@@ -474,6 +474,16 @@ const ChatBox = (
|
||||
};
|
||||
}, [router.query]);
|
||||
|
||||
useEffect(() => {
|
||||
event.on('guideClick', ({ text }: { text: string }) => {
|
||||
if (!text) return;
|
||||
handleSubmit((data) => sendPrompt(data, text))();
|
||||
});
|
||||
|
||||
return () => {
|
||||
event.off('guideClick');
|
||||
};
|
||||
}, [handleSubmit, sendPrompt]);
|
||||
useEffect(() => {
|
||||
const listen = () => {
|
||||
cancelBroadcast();
|
||||
@@ -497,15 +507,7 @@ const ChatBox = (
|
||||
<ChatAvatar src={appAvatar} type={'AI'} />
|
||||
{/* message */}
|
||||
<Card order={2} mt={2} {...MessageCardStyle} bg={'white'} maxW={messageCardMaxW}>
|
||||
<Markdown
|
||||
source={`~~~guide \n${welcomeText}`}
|
||||
isChatting={false}
|
||||
onClick={(e) => {
|
||||
const val = e?.data;
|
||||
if (e?.event !== EventNameEnum.guideClick || !val) return;
|
||||
handleSubmit((data) => sendPrompt(data, val))();
|
||||
}}
|
||||
/>
|
||||
<Markdown source={`~~~guide \n${welcomeText}`} isChatting={false} />
|
||||
</Card>
|
||||
</Flex>
|
||||
)}
|
||||
|
@@ -106,7 +106,13 @@ const Navbar = ({ unread }: { unread: number }) => {
|
||||
cursor={'pointer'}
|
||||
onClick={() => router.push('/account')}
|
||||
>
|
||||
<Avatar w={'36px'} h={'36px'} src={userInfo?.avatar} fallbackSrc={HUMAN_ICON} />
|
||||
<Avatar
|
||||
w={'36px'}
|
||||
h={'36px'}
|
||||
borderRadius={'none'}
|
||||
src={userInfo?.avatar}
|
||||
fallbackSrc={HUMAN_ICON}
|
||||
/>
|
||||
</Box>
|
||||
{/* 导航列表 */}
|
||||
<Box flex={1}>
|
||||
|
@@ -4,13 +4,37 @@ import ReactMarkdown from 'react-markdown';
|
||||
import RemarkGfm from 'remark-gfm';
|
||||
import RemarkMath from 'remark-math';
|
||||
import RehypeKatex from 'rehype-katex';
|
||||
import { event } from '@/utils/plugin/eventbus';
|
||||
|
||||
import 'katex/dist/katex.min.css';
|
||||
import styles from '../index.module.scss';
|
||||
import { EventNameEnum } from '../constant';
|
||||
import Image from '../img/Image';
|
||||
|
||||
const Guide = ({ text, onClick }: { text: string; onClick?: (e: any) => void }) => {
|
||||
const formatText = useMemo(() => text.replace(/\[(.*?)\]/g, '[$1]()'), [text]);
|
||||
function Link(e: any) {
|
||||
const href = e.href;
|
||||
const text = String(e.children);
|
||||
return (
|
||||
<Box as={'li'} py={1} m={0}>
|
||||
<Box
|
||||
as={'span'}
|
||||
color={'blue.600'}
|
||||
textDecoration={'underline'}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
if (href) {
|
||||
return window.open(href, '_blank');
|
||||
}
|
||||
event.emit('guideClick', { text });
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const Guide = ({ text }: { text: string }) => {
|
||||
const formatText = useMemo(() => text.replace(/\[(.*?)\]($|\n)/g, '[$1]()\n'), [text]);
|
||||
|
||||
return (
|
||||
<ReactMarkdown
|
||||
@@ -18,27 +42,8 @@ const Guide = ({ text, onClick }: { text: string; onClick?: (e: any) => void })
|
||||
remarkPlugins={[RemarkGfm, RemarkMath]}
|
||||
rehypePlugins={[RehypeKatex]}
|
||||
components={{
|
||||
a({ children }: any) {
|
||||
return (
|
||||
<Box as={'li'} py={1} m={0}>
|
||||
<Box
|
||||
as={'span'}
|
||||
color={'blue.600'}
|
||||
textDecoration={'underline'}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
if (!onClick) return;
|
||||
onClick({
|
||||
event: EventNameEnum.guideClick,
|
||||
data: String(children)
|
||||
});
|
||||
}}
|
||||
>
|
||||
{String(children)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
a: Link,
|
||||
img: Image
|
||||
}}
|
||||
>
|
||||
{formatText}
|
||||
|
@@ -1,3 +0,0 @@
|
||||
export enum EventNameEnum {
|
||||
guideClick = 'guideClick'
|
||||
}
|
@@ -22,6 +22,7 @@ const MdImage = ({ src }: { src?: string }) => {
|
||||
fallbackStrategy={'onError'}
|
||||
cursor={succeed ? 'pointer' : 'default'}
|
||||
loading="eager"
|
||||
objectFit={'contain'}
|
||||
onLoad={() => {
|
||||
setIsLoading(false);
|
||||
setSucceed(true);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import RemarkGfm from 'remark-gfm';
|
||||
import RemarkMath from 'remark-math';
|
||||
@@ -15,7 +15,7 @@ const MermaidCodeBlock = dynamic(() => import('./img/MermaidCodeBlock'));
|
||||
const MdImage = dynamic(() => import('./img/Image'));
|
||||
const ChatGuide = dynamic(() => import('./chat/Guide'));
|
||||
|
||||
function Code({ inline, className, children, onClick }: any) {
|
||||
function Code({ inline, className, children }: any) {
|
||||
const match = /language-(\w+)/.exec(className || '');
|
||||
const codeType = match?.[1];
|
||||
|
||||
@@ -24,7 +24,7 @@ function Code({ inline, className, children, onClick }: any) {
|
||||
}
|
||||
|
||||
if (codeType === 'guide') {
|
||||
return <ChatGuide text={String(children)} onClick={onClick} />;
|
||||
return <ChatGuide text={String(children)} />;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -33,28 +33,19 @@ function Code({ inline, className, children, onClick }: any) {
|
||||
</CodeLight>
|
||||
);
|
||||
}
|
||||
|
||||
function Image({ src }: { src?: string }) {
|
||||
return <MdImage src={src} />;
|
||||
}
|
||||
|
||||
const Markdown = ({
|
||||
source,
|
||||
isChatting = false,
|
||||
onClick
|
||||
}: {
|
||||
source: string;
|
||||
isChatting?: boolean;
|
||||
onClick?: (e: any) => void;
|
||||
}) => {
|
||||
const Markdown = ({ source, isChatting = false }: { source: string; isChatting?: boolean }) => {
|
||||
const components = useMemo(
|
||||
() => ({
|
||||
img: Image,
|
||||
pre: 'div',
|
||||
p: 'div',
|
||||
code: (props: any) => <Code {...props} onClick={onClick} />
|
||||
code: Code
|
||||
}),
|
||||
[onClick]
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@@ -53,8 +53,8 @@ export async function generateVector(): Promise<any> {
|
||||
|
||||
dataItems = [
|
||||
{
|
||||
q: data.q.replace(/[\x00-\x1F]/g, ' '),
|
||||
a: data.a.replace(/[\x00-\x1F]/g, ' ')
|
||||
q: data.q.replace(/[\x00-\x08]/g, ' '),
|
||||
a: data.a.replace(/[\x00-\x08]/g, ' ')
|
||||
}
|
||||
];
|
||||
|
||||
|
@@ -282,7 +282,7 @@ export const simpleText = (text: string) => {
|
||||
text = text.replace(/\n{2,}/g, '\n');
|
||||
text = text.replace(/\s{2,}/g, ' ');
|
||||
|
||||
text = text.replace(/[\x00-\x1F]/g, ' ');
|
||||
text = text.replace(/[\x00-\x08]/g, ' ');
|
||||
|
||||
return text;
|
||||
};
|
||||
|
18
client/src/utils/plugin/eventbus.ts
Normal file
18
client/src/utils/plugin/eventbus.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export enum EventNameEnum {
|
||||
guideClick = 'guideClick'
|
||||
}
|
||||
type EventNameType = `${EventNameEnum}`;
|
||||
|
||||
export const event = {
|
||||
list: new Map<EventNameType, Function>(),
|
||||
on: function (name: EventNameType, fn: Function) {
|
||||
this.list.set(name, fn);
|
||||
},
|
||||
emit: function (name: EventNameType, data: Record<string, any> = {}) {
|
||||
const fn = this.list.get(name);
|
||||
fn && fn(data);
|
||||
},
|
||||
off: function (name: EventNameType) {
|
||||
this.list.delete(name);
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user