feat: img compress;perf: color.prompt response

This commit is contained in:
archer
2023-05-03 21:42:23 +08:00
parent 17a42ac0cc
commit 91b02bbfd9
7 changed files with 87 additions and 19 deletions

View File

@@ -39,7 +39,7 @@ const NavbarPhone = ({
px={7} px={7}
> >
<Box onClick={onOpen}> <Box onClick={onOpen}>
<MyIcon name="menu" width={'20px'} height={'20px'} color={'blackAlpha.600'}></MyIcon> <MyIcon name="menu" width={'20px'} height={'20px'} color={'blackAlpha.700'}></MyIcon>
</Box> </Box>
</Flex> </Flex>
<Drawer isOpen={isOpen} placement="left" size={'xs'} onClose={onClose}> <Drawer isOpen={isOpen} placement="left" size={'xs'} onClose={onClose}>

View File

@@ -83,7 +83,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const temperature = (modelConstantsData.maxTemperature * (model.chat.temperature / 10)).toFixed( const temperature = (modelConstantsData.maxTemperature * (model.chat.temperature / 10)).toFixed(
2 2
); );
// console.log(filterPrompts);
// 发出请求 // 发出请求
const { streamResponse } = await modelServiceToolMap[model.chat.chatModel].chatCompletion({ const { streamResponse } = await modelServiceToolMap[model.chat.chatModel].chatCompletion({

View File

@@ -99,7 +99,7 @@ const SlideBar = ({
fetchMyModels(); fetchMyModels();
fetchCollectionModels(); fetchCollectionModels();
loadChatHistory(); loadChatHistory();
}, 1500); }, 1000);
}, [fetchCollectionModels, fetchMyModels, loadChatHistory]); }, [fetchCollectionModels, fetchMyModels, loadChatHistory]);
/** /**

View File

@@ -432,7 +432,7 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
name={'menu'} name={'menu'}
w={'20px'} w={'20px'}
h={'20px'} h={'20px'}
fill={useColorModeValue('blackAlpha.700', 'white')} color={useColorModeValue('blackAlpha.700', 'white')}
/> />
</Box> </Box>
<Box>{chatData?.name}</Box> <Box>{chatData?.name}</Box>

View File

@@ -26,7 +26,7 @@ import { formatPrice } from '@/utils/user';
import { useConfirm } from '@/hooks/useConfirm'; import { useConfirm } from '@/hooks/useConfirm';
import { useSelectFile } from '@/hooks/useSelectFile'; import { useSelectFile } from '@/hooks/useSelectFile';
import { useToast } from '@/hooks/useToast'; import { useToast } from '@/hooks/useToast';
import { fileToBase64 } from '@/utils/file'; import { fileToBase64, compressImg } from '@/utils/file';
const ModelEditForm = ({ const ModelEditForm = ({
formHooks, formHooks,
@@ -52,17 +52,19 @@ const ModelEditForm = ({
async (e: File[]) => { async (e: File[]) => {
const file = e[0]; const file = e[0];
if (!file) return; if (!file) return;
try {
const base64 = await compressImg({
file
});
if (file.size > 100 * 1024) { setValue('avatar', base64);
return toast({ setRefresh((state) => !state);
title: '头像需小于 100kb', } catch (err: any) {
toast({
title: typeof err === 'string' ? err : '头像选择异常',
status: 'warning' status: 'warning'
}); });
} }
const base64 = (await fileToBase64(file)) as string;
setValue('avatar', base64);
setRefresh((state) => !state);
}, },
[setValue, toast] [setValue, toast]
); );
@@ -195,6 +197,7 @@ const ModelEditForm = ({
<Flex mt={4} alignItems={'center'}> <Flex mt={4} alignItems={'center'}>
<Box mr={4}></Box> <Box mr={4}></Box>
<Switch <Switch
isDisabled={!isOwner}
isChecked={getValues('chat.useKb')} isChecked={getValues('chat.useKb')}
onChange={() => { onChange={() => {
setValue('chat.useKb', !getValues('chat.useKb')); setValue('chat.useKb', !getValues('chat.useKb'));

View File

@@ -142,14 +142,16 @@ export const resStreamResponse = async ({
prompts prompts
}); });
// push system prompt setTimeout(() => {
!stream.destroyed && // push system prompt
systemPrompt && !stream.destroyed &&
stream.push(`${SYSTEM_PROMPT_PREFIX}${systemPrompt.replace(/\n/g, '<br/>')}`); systemPrompt &&
stream.push(`${SYSTEM_PROMPT_PREFIX}${systemPrompt.replace(/\n/g, '<br/>')}`);
// close stream // close stream
!stream.destroyed && stream.push(null); !stream.destroyed && stream.push(null);
stream.destroy(); stream.destroy();
}, 100);
return { responseContent, totalTokens, finishMessages }; return { responseContent, totalTokens, finishMessages };
}; };

View File

@@ -190,3 +190,67 @@ export const fileToBase64 = (file: File) => {
reader.onerror = (error) => reject(error); reader.onerror = (error) => reject(error);
}); });
}; };
/**
* compress image. response base64
* @param maxSize The max size of the compressed image
*/
export const compressImg = ({
file,
maxW = 200,
maxH = 200,
maxSize = 1024 * 100
}: {
file: File;
maxW?: number;
maxH?: number;
maxSize?: number;
}) =>
new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const img = new Image();
// @ts-ignore
img.src = reader.result;
img.onload = () => {
let width = img.width;
let height = img.height;
if (width > height) {
if (width > maxW) {
height *= maxW / width;
width = maxW;
}
} else {
if (height > maxH) {
width *= maxH / height;
height = maxH;
}
}
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
if (!ctx) {
return reject('压缩图片异常');
}
ctx.drawImage(img, 0, 0, width, height);
const compressedDataUrl = canvas.toDataURL(file.type, 1);
// 移除 canvas 元素
canvas.remove();
if (compressedDataUrl.length > maxSize) {
return reject('图片太大了');
}
resolve(compressedDataUrl);
};
};
reader.onerror = (err) => {
console.log(err);
reject('压缩图片异常');
};
});