mirror of
https://github.com/lobehub/lobehub
synced 2026-04-26 20:17:18 +00:00
* ✨ feat: 完成 ai provider 部分的新增、menu 列表、卡片列表与开启关闭,支持 model 开关,并优化列表展示,支持 model 拉取。完成 ai models 新增和修改逻辑、排序完整实现,优化开关体验,完成 chat model select 实现。完成 provider 的配置修改与删除开发
update config
fix
add sdk type
fix toggle search issue
improve enable
优化模型开关操作体验
feat: 完成 chat model select 部分实现
fix auth
兼容 client db 废弃模式
fix test
完成 provider 的配置修改与删除开发
clean
* 修正未登录态的数据
* fix db sql
* fix lint
* update
* improve loading
* improve model list empty state
103 lines
2.8 KiB
TypeScript
103 lines
2.8 KiB
TypeScript
import { ActionIcon, Icon, Tooltip } from '@lobehub/ui';
|
|
import { Dropdown, MenuProps, Upload } from 'antd';
|
|
import { css, cx } from 'antd-style';
|
|
import { FileUp, FolderUp, ImageUp, Paperclip } from 'lucide-react';
|
|
import { memo } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { useModelSupportVision } from '@/hooks/useModelSupportVision';
|
|
import { useAgentStore } from '@/store/agent';
|
|
import { agentSelectors } from '@/store/agent/slices/chat';
|
|
import { useFileStore } from '@/store/file';
|
|
|
|
const hotArea = css`
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
inset: 0;
|
|
background-color: transparent;
|
|
}
|
|
`;
|
|
|
|
const FileUpload = memo(() => {
|
|
const { t } = useTranslation('chat');
|
|
|
|
const upload = useFileStore((s) => s.uploadChatFiles);
|
|
|
|
const model = useAgentStore(agentSelectors.currentAgentModel);
|
|
|
|
const canUploadImage = useModelSupportVision(model);
|
|
|
|
const items: MenuProps['items'] = [
|
|
{
|
|
disabled: !canUploadImage,
|
|
icon: <Icon icon={ImageUp} style={{ fontSize: '16px' }} />,
|
|
key: 'upload-image',
|
|
label: canUploadImage ? (
|
|
<Upload
|
|
accept={'image/*'}
|
|
beforeUpload={async (file) => {
|
|
await upload([file]);
|
|
|
|
return false;
|
|
}}
|
|
multiple
|
|
showUploadList={false}
|
|
>
|
|
<div className={cx(hotArea)}>{t('upload.action.imageUpload')}</div>
|
|
</Upload>
|
|
) : (
|
|
<Tooltip placement={'right'} title={t('upload.action.imageDisabled')}>
|
|
<div className={cx(hotArea)}>{t('upload.action.imageUpload')}</div>
|
|
</Tooltip>
|
|
),
|
|
},
|
|
{
|
|
icon: <Icon icon={FileUp} style={{ fontSize: '16px' }} />,
|
|
key: 'upload-file',
|
|
label: (
|
|
<Upload
|
|
beforeUpload={async (file) => {
|
|
if (!canUploadImage && file.type.startsWith('image')) return false;
|
|
|
|
await upload([file]);
|
|
|
|
return false;
|
|
}}
|
|
multiple
|
|
showUploadList={false}
|
|
>
|
|
<div className={cx(hotArea)}>{t('upload.action.fileUpload')}</div>
|
|
</Upload>
|
|
),
|
|
},
|
|
{
|
|
icon: <Icon icon={FolderUp} style={{ fontSize: '16px' }} />,
|
|
key: 'upload-folder',
|
|
label: (
|
|
<Upload
|
|
beforeUpload={async (file) => {
|
|
if (!canUploadImage && file.type.startsWith('image')) return false;
|
|
|
|
await upload([file]);
|
|
|
|
return false;
|
|
}}
|
|
directory
|
|
multiple={true}
|
|
showUploadList={false}
|
|
>
|
|
<div className={cx(hotArea)}>{t('upload.action.folderUpload')}</div>
|
|
</Upload>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<Dropdown menu={{ items }} placement="top">
|
|
<ActionIcon icon={Paperclip} placement={'bottom'} title={t('upload.action.tooltip')} />
|
|
</Dropdown>
|
|
);
|
|
});
|
|
|
|
export default FileUpload;
|