Skip to content

Commit

Permalink
feat: 完成 ai provider 排序完整实现,优化开关体验
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Dec 29, 2024
1 parent 81e9d58 commit 1143863
Show file tree
Hide file tree
Showing 12 changed files with 319 additions and 89 deletions.
2 changes: 0 additions & 2 deletions src/app/(main)/settings/provider/(detail)/[id]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use client';

import { Divider } from 'antd';
import { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

Expand All @@ -11,7 +10,6 @@ const ProviderDetail = memo<ProviderConfigProps>((card) => {
return (
<Flexbox gap={24} paddingBlock={8}>
<ProviderConfig {...card} />
<Divider dashed style={{ margin: 0 }} />
<ModelList id={card.id} {...card.modelList} />
</Flexbox>
);
Expand Down
20 changes: 8 additions & 12 deletions src/app/(main)/settings/provider/(list)/ProviderGrid/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ProviderCombine, ProviderIcon } from '@lobehub/icons';
import { Avatar } from '@lobehub/ui';
import { Divider, Skeleton, Switch, Typography } from 'antd';
import { Divider, Skeleton, Typography } from 'antd';
import { createStyles } from 'antd-style';
import Link from 'next/link';
import { memo, useState } from 'react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { aiProviderSelectors, useAiInfraStore } from '@/store/aiInfra';
import InstantSwitch from '@/components/InstantSwitch';
import { useAiInfraStore } from '@/store/aiInfra';
import { AiProviderListItem } from '@/types/aiProvider';

const { Paragraph } = Typography;
Expand Down Expand Up @@ -69,9 +70,6 @@ const ProviderCard = memo<ProviderCardProps>(
const { t } = useTranslation('providers');
const { cx, styles, theme } = useStyles();
const toggleProviderEnabled = useAiInfraStore((s) => s.toggleProviderEnabled);
const isProviderLoading = useAiInfraStore(aiProviderSelectors.isProviderLoading(id));

const [checked, setChecked] = useState(enabled);

if (loading)
return (
Expand Down Expand Up @@ -115,12 +113,10 @@ const ProviderCard = memo<ProviderCardProps>(
<Divider style={{ margin: '4px 0' }} />
<Flexbox horizontal justify={'space-between'} paddingBlock={'8px 0'}>
<div />
<Switch
checked={checked}
loading={isProviderLoading}
onChange={(checked) => {
setChecked(checked);
toggleProviderEnabled(id, checked);
<InstantSwitch
enabled={enabled}
onChange={async (checked) => {
await toggleProviderEnabled(id, checked);
}}
size={'small'}
/>
Expand Down
111 changes: 59 additions & 52 deletions src/app/(main)/settings/provider/features/ModelList/ModelTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ActionIcon, Icon } from '@lobehub/ui';
import { Button, Space, Typography } from 'antd';
import { Button, Skeleton, Space, Typography } from 'antd';
import { useTheme } from 'antd-style';
import { CircleX, LucideRefreshCcwDot, PlusIcon } from 'lucide-react';
import { memo, useState } from 'react';
Expand All @@ -16,10 +16,10 @@ interface ModelFetcherProps {
const ModelTitle = memo<ModelFetcherProps>(({ provider }) => {
const theme = useTheme();
const { t } = useTranslation('setting');
const [fetchRemoteModelList, clearObtainedModels] = useAiInfraStore((s) => [
s.fetchRemoteModelList,
s.clearRemoteModels,
]);
const [fetchRemoteModelList, clearObtainedModels, useFetchAiProviderModels] = useAiInfraStore(
(s) => [s.fetchRemoteModelList, s.clearRemoteModels, s.useFetchAiProviderModels],
);
const { isLoading } = useFetchAiProviderModels(provider);

const [totalModels, hasRemoteModels] = useAiInfraStore((s) => [
// s.modelSearchKeyword,
Expand All @@ -41,54 +41,61 @@ const ModelTitle = memo<ModelFetcherProps>(({ provider }) => {
<Flexbox align={'center'} gap={8} horizontal>
<Typography.Text style={{ fontSize: 16, fontWeight: 'bold' }}>模型列表</Typography.Text>

<Typography.Text style={{ fontSize: 12 }} type={'secondary'}>
<div style={{ display: 'flex', lineHeight: '24px' }}>
{t('llm.modelList.total', { count: totalModels })}
{hasRemoteModels && (
<ActionIcon
icon={CircleX}
loading={clearRemoteModelsLoading}
onClick={async () => {
setClearRemoteModelsLoading(true);
await clearObtainedModels(provider);
setClearRemoteModelsLoading(false);
}}
size={'small'}
title={t('llm.fetcher.clear')}
/>
)}
</div>
</Typography.Text>
</Flexbox>

<Flexbox gap={8} horizontal>
{/*{totalModels >= 30 && (*/}
{/* <Input*/}
{/* onChange={(e) => {*/}
{/* useAiInfraStore.setState({ modelSearchKeyword: e.target.value });*/}
{/* }}*/}
{/* placeholder={'搜索模型...'}*/}
{/* prefix={<Icon icon={SearchIcon} />}*/}
{/* size={'small'}*/}
{/* value={searchKeyword}*/}
{/* />*/}
{/*)}*/}
<Space.Compact>
<Button
icon={<Icon icon={LucideRefreshCcwDot} />}
loading={fetchRemoteModelsLoading}
onClick={async () => {
setFetchRemoteModelsLoading(true);
await fetchRemoteModelList(provider);
setFetchRemoteModelsLoading(false);
}}
size={'small'}
>
{fetchRemoteModelsLoading ? t('llm.fetcher.fetching') : t('llm.fetcher.fetch')}
</Button>
<Button icon={<Icon icon={PlusIcon} />} size={'small'}></Button>
</Space.Compact>
{isLoading ? (
<Skeleton.Button active style={{ height: 22 }} />
) : (
<Typography.Text style={{ fontSize: 12 }} type={'secondary'}>
<div style={{ display: 'flex', lineHeight: '24px' }}>
{t('llm.modelList.total', { count: totalModels })}
{hasRemoteModels && (
<ActionIcon
icon={CircleX}
loading={clearRemoteModelsLoading}
onClick={async () => {
setClearRemoteModelsLoading(true);
await clearObtainedModels(provider);
setClearRemoteModelsLoading(false);
}}
size={'small'}
title={t('llm.fetcher.clear')}
/>
)}
</div>
</Typography.Text>
)}
</Flexbox>
{isLoading ? (
<Skeleton.Button active size={'small'} style={{ width: 120 }} />
) : (
<Flexbox gap={8} horizontal>
{/*{totalModels >= 30 && (*/}
{/* <Input*/}
{/* onChange={(e) => {*/}
{/* useAiInfraStore.setState({ modelSearchKeyword: e.target.value });*/}
{/* }}*/}
{/* placeholder={'搜索模型...'}*/}
{/* prefix={<Icon icon={SearchIcon} />}*/}
{/* size={'small'}*/}
{/* value={searchKeyword}*/}
{/* />*/}
{/*)}*/}
<Space.Compact>
<Button
icon={<Icon icon={LucideRefreshCcwDot} />}
loading={fetchRemoteModelsLoading}
onClick={async () => {
setFetchRemoteModelsLoading(true);
await fetchRemoteModelList(provider);
setFetchRemoteModelsLoading(false);
}}
size={'small'}
>
{fetchRemoteModelsLoading ? t('llm.fetcher.fetching') : t('llm.fetcher.fetch')}
</Button>
<Button icon={<Icon icon={PlusIcon} />} size={'small'}></Button>
</Space.Compact>
</Flexbox>
)}{' '}
</Flexbox>
</Flexbox>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Trans, useTranslation } from 'react-i18next';
import { Center, Flexbox } from 'react-layout-kit';
import urlJoin from 'url-join';

import InstantSwitch from '@/components/InstantSwitch';
import { FORM_STYLE } from '@/const/layoutTokens';
import { AES_GCM_URL, BASE_PROVIDER_DOC_URL } from '@/const/url';
import { isServerMode } from '@/const/version';
Expand Down Expand Up @@ -258,11 +259,11 @@ const ProviderConfig = memo<ProviderConfigProps>(
isLoading ? (
<Skeleton.Button active className={styles.switchLoading} />
) : (
<Switch
onChange={(enabled) => {
toggleProviderEnabled(id as any, enabled);
<InstantSwitch
enabled={enabled}
onChange={async (enabled) => {
await toggleProviderEnabled(id as any, enabled);
}}
value={enabled}
/>
)
) : undefined}
Expand Down
28 changes: 28 additions & 0 deletions src/components/InstantSwitch/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Switch, SwitchProps } from 'antd';
import { memo, useState } from 'react';

interface InstantSwitchProps {
enabled: boolean;
onChange: (enabled: boolean) => Promise<void>;
size?: SwitchProps['size'];
}

const InstantSwitch = memo<InstantSwitchProps>(({ enabled, onChange, size }) => {
const [value, setValue] = useState(enabled);
const [loading, setLoading] = useState(false);
return (
<Switch
loading={loading}
onChange={async (enabled) => {
setLoading(true);
setValue(enabled);
await onChange(enabled);
setLoading(false);
}}
size={size}
value={value}
/>
);
});

export default InstantSwitch;
11 changes: 0 additions & 11 deletions src/config/aiModels/ollama.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,6 @@ const ollamaChatModels: AIChatModelCard[] = [
id: 'qwen2.5:72b',
type: 'chat',
},
{
abilities: {
functionCall: true,
},
contextWindowTokens: 128_000,
description: 'Qwen2.5 是阿里巴巴的新一代大规模语言模型,以优异的性能支持多元化的应用需求。',
displayName: 'Qwen2.5 7B',
enabled: true,
id: 'qwen2.5',
type: 'chat',
},
{
abilities: {
functionCall: true,
Expand Down
Loading

0 comments on commit 1143863

Please sign in to comment.