@lobehub/chat 0.111.1 → 0.111.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/locales/en_US/plugin.json +2 -1
- package/locales/fr_FR/plugin.json +2 -1
- package/locales/ja_JP/plugin.json +2 -1
- package/locales/ko_KR/plugin.json +2 -1
- package/locales/ru_RU/plugin.json +2 -1
- package/locales/zh_CN/plugin.json +1 -0
- package/locales/zh_TW/plugin.json +2 -1
- package/package.json +1 -1
- package/src/app/chat/features/ChatInput/ActionBar/Clear.tsx +2 -2
- package/src/app/chat/features/Migration/Modal.tsx +2 -2
- package/src/components/FileList/FileItem.tsx +2 -0
- package/src/components/HotKeys/index.tsx +13 -8
- package/src/const/hotkeys.ts +1 -0
- package/src/features/DataImporter/index.tsx +2 -2
- package/src/features/PluginSettingsModal/index.tsx +2 -0
- package/src/features/PluginStore/PluginItem.tsx +38 -37
- package/src/features/PluginStore/PluginSettings.tsx +2 -2
- package/src/features/PluginStore/index.tsx +56 -23
- package/src/layout/GlobalLayout/Locale.tsx +1 -1
- package/src/locales/default/plugin.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.111.2](https://github.com/lobehub/lobe-chat/compare/v0.111.1...v0.111.2)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-12-13**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Change topic-deletion hotkey.
|
|
12
|
+
|
|
13
|
+
#### 💄 Styles
|
|
14
|
+
|
|
15
|
+
- **misc**: Fix image display in safari (fix.
|
|
16
|
+
|
|
17
|
+
<br/>
|
|
18
|
+
|
|
19
|
+
<details>
|
|
20
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
21
|
+
|
|
22
|
+
#### What's fixed
|
|
23
|
+
|
|
24
|
+
- **misc**: Change topic-deletion hotkey, closes [#616](https://github.com/lobehub/lobe-chat/issues/616) ([912ff45](https://github.com/lobehub/lobe-chat/commit/912ff45))
|
|
25
|
+
|
|
26
|
+
#### Styles
|
|
27
|
+
|
|
28
|
+
- **misc**: Fix image display in safari (fix, closes [#571](https://github.com/lobehub/lobe-chat/issues/571) ([4beefa7](https://github.com/lobehub/lobe-chat/commit/4beefa7))
|
|
29
|
+
|
|
30
|
+
</details>
|
|
31
|
+
|
|
32
|
+
<div align="right">
|
|
33
|
+
|
|
34
|
+
[](#readme-top)
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
|
|
5
38
|
### [Version 0.111.1](https://github.com/lobehub/lobe-chat/compare/v0.111.0...v0.111.1)
|
|
6
39
|
|
|
7
40
|
<sup>Released on **2023-12-13**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.111.
|
|
3
|
+
"version": "0.111.2",
|
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -6,7 +6,7 @@ import { useHotkeys } from 'react-hotkeys-hook';
|
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
|
|
8
8
|
import HotKeys from '@/components/HotKeys';
|
|
9
|
-
import { CLEAN_MESSAGE_KEY, PREFIX_KEY } from '@/const/hotkeys';
|
|
9
|
+
import { CLEAN_MESSAGE_KEY, META_KEY, PREFIX_KEY } from '@/const/hotkeys';
|
|
10
10
|
import { useChatStore } from '@/store/chat';
|
|
11
11
|
import { useFileStore } from '@/store/file';
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ const Clear = memo(() => {
|
|
|
14
14
|
const { t } = useTranslation('setting');
|
|
15
15
|
const [clearMessage] = useChatStore((s) => [s.clearMessage]);
|
|
16
16
|
const [clearImageList] = useFileStore((s) => [s.clearImageList]);
|
|
17
|
-
const hotkeys = [PREFIX_KEY, CLEAN_MESSAGE_KEY].join('+');
|
|
17
|
+
const hotkeys = [META_KEY, PREFIX_KEY, CLEAN_MESSAGE_KEY].join('+');
|
|
18
18
|
|
|
19
19
|
const resetConversation = useCallback(() => {
|
|
20
20
|
clearMessage();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Icon } from '@lobehub/ui';
|
|
2
2
|
import { Button, Result } from 'antd';
|
|
3
|
-
import {
|
|
3
|
+
import { CheckCircle, CpuIcon } from 'lucide-react';
|
|
4
4
|
import { memo, useState } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { Center } from 'react-layout-kit';
|
|
@@ -48,7 +48,7 @@ const MigrationModal = memo<MigrationModalProps>(({ setOpen, open, state: dbStat
|
|
|
48
48
|
{t('dbV1.action.start')}
|
|
49
49
|
</Button>
|
|
50
50
|
}
|
|
51
|
-
icon={<Icon icon={
|
|
51
|
+
icon={<Icon icon={CheckCircle} />}
|
|
52
52
|
status={'success'}
|
|
53
53
|
style={{ paddingBlock: 24 }}
|
|
54
54
|
subTitle={t('dbV1.upgrade.success.subTitle')}
|
|
@@ -62,9 +62,11 @@ const FileItem = memo<FileItemProps>(({ editable, id, alwaysShowClose }) => {
|
|
|
62
62
|
}
|
|
63
63
|
alt={data?.name || id || ''}
|
|
64
64
|
alwaysShowActions={alwaysShowClose}
|
|
65
|
+
height={'auto'}
|
|
65
66
|
isLoading={isLoading}
|
|
66
67
|
size={IMAGE_SIZE as any}
|
|
67
68
|
src={data?.url}
|
|
69
|
+
style={{ height: 'auto' }}
|
|
68
70
|
wrapperClassName={cx(styles.image, editable && styles.editableImage)}
|
|
69
71
|
/>
|
|
70
72
|
);
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { Icon } from '@lobehub/ui';
|
|
3
4
|
import { createStyles } from 'antd-style';
|
|
5
|
+
import { isString } from 'lodash-es';
|
|
6
|
+
import { Command, Delete, Option } from 'lucide-react';
|
|
4
7
|
import { memo, useEffect, useState } from 'react';
|
|
5
8
|
import { Flexbox } from 'react-layout-kit';
|
|
6
9
|
|
|
7
|
-
import { CLEAN_MESSAGE_KEY, PREFIX_KEY } from '@/const/hotkeys';
|
|
10
|
+
import { CLEAN_MESSAGE_KEY, META_KEY, PREFIX_KEY } from '@/const/hotkeys';
|
|
8
11
|
import { isApplePlatform } from '@/utils/platform';
|
|
9
12
|
|
|
10
13
|
const useStyles = createStyles(
|
|
@@ -13,14 +16,15 @@ const useStyles = createStyles(
|
|
|
13
16
|
|
|
14
17
|
span {
|
|
15
18
|
font-weight: 600;
|
|
16
|
-
opacity: 0.5;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
kbd {
|
|
20
|
-
|
|
22
|
+
min-width: 16px;
|
|
23
|
+
padding: 3px 6px;
|
|
21
24
|
|
|
22
25
|
line-height: 1;
|
|
23
|
-
color: ${token.
|
|
26
|
+
color: ${token.colorTextDescription};
|
|
27
|
+
text-align: center;
|
|
24
28
|
|
|
25
29
|
background: ${token.colorBgContainer};
|
|
26
30
|
border: 1px solid ${token.colorBorderSecondary};
|
|
@@ -42,9 +46,10 @@ const HotKeys = memo<HotKeysProps>(({ keys, desc }) => {
|
|
|
42
46
|
const visibility = typeof window === 'undefined' ? 'hidden' : 'visible';
|
|
43
47
|
|
|
44
48
|
useEffect(() => {
|
|
45
|
-
const mapping: Record<string,
|
|
46
|
-
[CLEAN_MESSAGE_KEY]: isApplePlatform() ?
|
|
47
|
-
[
|
|
49
|
+
const mapping: Record<string, any> = {
|
|
50
|
+
[CLEAN_MESSAGE_KEY]: isApplePlatform() ? <Icon icon={Delete} /> : 'backspace',
|
|
51
|
+
[META_KEY]: isApplePlatform() ? <Icon icon={Command} /> : 'ctrl',
|
|
52
|
+
[PREFIX_KEY]: isApplePlatform() ? <Icon icon={Option} /> : 'alt',
|
|
48
53
|
};
|
|
49
54
|
const newValue = keys
|
|
50
55
|
.split('+')
|
|
@@ -57,7 +62,7 @@ const HotKeys = memo<HotKeysProps>(({ keys, desc }) => {
|
|
|
57
62
|
<Flexbox align={'center'} className={styles} gap={2} horizontal>
|
|
58
63
|
{keysGroup.map((key, index) => (
|
|
59
64
|
<kbd key={index}>
|
|
60
|
-
<span style={{ visibility }}>{key.toUpperCase()}</span>
|
|
65
|
+
<span style={{ visibility }}>{isString(key) ? key.toUpperCase() : key}</span>
|
|
61
66
|
</kbd>
|
|
62
67
|
))}
|
|
63
68
|
</Flexbox>
|
package/src/const/hotkeys.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Icon } from '@lobehub/ui';
|
|
2
2
|
import { Button, Result, Table, Upload } from 'antd';
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
|
-
import {
|
|
4
|
+
import { CheckCircle, ImportIcon } from 'lucide-react';
|
|
5
5
|
import React, { ReactNode, memo, useState } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { Center, Flexbox } from 'react-layout-kit';
|
|
@@ -169,7 +169,7 @@ const DataImporter = memo<DataImporterProps>(({ children, onFinishImport }) => {
|
|
|
169
169
|
{t('importModal.finish.start')}
|
|
170
170
|
</Button>
|
|
171
171
|
}
|
|
172
|
-
icon={<Icon icon={
|
|
172
|
+
icon={<Icon icon={CheckCircle} />}
|
|
173
173
|
status={'success'}
|
|
174
174
|
style={{ paddingBlock: 24 }}
|
|
175
175
|
subTitle={
|
|
@@ -25,6 +25,8 @@ const PluginSettingsModal = memo<PluginSettingsModalProps>(({ schema, onClose, i
|
|
|
25
25
|
const theme = useTheme();
|
|
26
26
|
return (
|
|
27
27
|
<Modal
|
|
28
|
+
cancelText={t('cancel', { ns: 'common' })}
|
|
29
|
+
okText={t('ok', { ns: 'common' })}
|
|
28
30
|
onCancel={onClose}
|
|
29
31
|
onOk={() => {
|
|
30
32
|
onClose();
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
|
|
2
|
-
import { Avatar, Tag } from '@lobehub/ui';
|
|
2
|
+
import { Avatar, Icon, Tag } from '@lobehub/ui';
|
|
3
3
|
import { Button } from 'antd';
|
|
4
|
-
import { createStyles } from 'antd-style';
|
|
4
|
+
import { createStyles, useResponsive } from 'antd-style';
|
|
5
|
+
import { BadgeCheck, CircleUser } from 'lucide-react';
|
|
5
6
|
import Link from 'next/link';
|
|
6
7
|
import { memo } from 'react';
|
|
7
8
|
import { useTranslation } from 'react-i18next';
|
|
@@ -14,13 +15,13 @@ import PluginSettings from './PluginSettings';
|
|
|
14
15
|
|
|
15
16
|
const useStyles = createStyles(({ css, token }) => ({
|
|
16
17
|
desc: css`
|
|
17
|
-
color: ${token.
|
|
18
|
+
color: ${token.colorTextDescription};
|
|
18
19
|
`,
|
|
19
20
|
link: css`
|
|
20
|
-
color: ${token.
|
|
21
|
+
color: ${token.colorText};
|
|
21
22
|
`,
|
|
22
23
|
tag: css`
|
|
23
|
-
|
|
24
|
+
color: ${token.colorTextSecondary};
|
|
24
25
|
`,
|
|
25
26
|
title: css`
|
|
26
27
|
font-size: ${token.fontSizeLG}px;
|
|
@@ -28,52 +29,52 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
28
29
|
line-height: 2;
|
|
29
30
|
`,
|
|
30
31
|
}));
|
|
31
|
-
const PluginItem = memo<LobeChatPluginMeta>(({ identifier,
|
|
32
|
+
const PluginItem = memo<LobeChatPluginMeta>(({ identifier, homepage, author, meta }) => {
|
|
32
33
|
const [installed, installing, installPlugin, unInstallPlugin] = useToolStore((s) => [
|
|
33
34
|
pluginSelectors.isPluginInstalled(identifier)(s),
|
|
34
35
|
pluginStoreSelectors.isPluginInstallLoading(identifier)(s),
|
|
35
36
|
s.installPlugin,
|
|
36
37
|
s.uninstallPlugin,
|
|
37
38
|
]);
|
|
39
|
+
const { mobile } = useResponsive();
|
|
38
40
|
const { styles } = useStyles();
|
|
39
41
|
|
|
40
42
|
const { t } = useTranslation('plugin');
|
|
41
43
|
return (
|
|
42
|
-
<Flexbox gap={8}
|
|
43
|
-
<Flexbox
|
|
44
|
-
<Avatar avatar={meta.avatar} size={56} style={{ flex: 'none' }} />
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<PluginSettings identifier={identifier} />
|
|
48
|
-
<Button
|
|
49
|
-
loading={installing}
|
|
50
|
-
onClick={() => {
|
|
51
|
-
if (installed) {
|
|
52
|
-
unInstallPlugin(identifier);
|
|
53
|
-
} else installPlugin(identifier);
|
|
54
|
-
}}
|
|
55
|
-
type={installed ? 'default' : 'primary'}
|
|
56
|
-
>
|
|
57
|
-
{t(installed ? 'store.uninstall' : 'store.install')}
|
|
58
|
-
</Button>
|
|
59
|
-
</Flexbox>
|
|
60
|
-
</Flexbox>
|
|
61
|
-
|
|
62
|
-
<Flexbox gap={4}>
|
|
63
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
64
|
-
<div className={styles.title}>{meta.title}</div>
|
|
65
|
-
<Tag className={styles.tag}> {identifier}</Tag>
|
|
66
|
-
</Flexbox>
|
|
67
|
-
<div className={styles.desc}>{meta.description}</div>
|
|
68
|
-
<Flexbox className={styles.link} gap={8} horizontal>
|
|
69
|
-
{author && (
|
|
44
|
+
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'}>
|
|
45
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
|
46
|
+
<Avatar avatar={meta.avatar} size={mobile ? 40 : 56} style={{ flex: 'none' }} />
|
|
47
|
+
<Flexbox gap={4}>
|
|
48
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
|
70
49
|
<Link className={styles.link} href={homepage} target={'_blank'}>
|
|
71
|
-
|
|
50
|
+
<div className={styles.title}>{meta.title}</div>
|
|
72
51
|
</Link>
|
|
73
|
-
|
|
74
|
-
|
|
52
|
+
|
|
53
|
+
<Tag
|
|
54
|
+
className={styles.tag}
|
|
55
|
+
icon={<Icon icon={author === 'LobeHub' ? BadgeCheck : CircleUser} />}
|
|
56
|
+
>
|
|
57
|
+
{author}
|
|
58
|
+
</Tag>
|
|
59
|
+
</Flexbox>
|
|
60
|
+
<div className={styles.desc}>{meta.description} </div>
|
|
75
61
|
</Flexbox>
|
|
76
62
|
</Flexbox>
|
|
63
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
|
64
|
+
<PluginSettings identifier={identifier} />
|
|
65
|
+
<Button
|
|
66
|
+
loading={installing}
|
|
67
|
+
onClick={() => {
|
|
68
|
+
if (installed) {
|
|
69
|
+
unInstallPlugin(identifier);
|
|
70
|
+
} else installPlugin(identifier);
|
|
71
|
+
}}
|
|
72
|
+
size={mobile ? 'small' : undefined}
|
|
73
|
+
type={installed ? 'default' : 'primary'}
|
|
74
|
+
>
|
|
75
|
+
{t(installed ? 'store.uninstall' : 'store.install')}
|
|
76
|
+
</Button>
|
|
77
|
+
</Flexbox>
|
|
77
78
|
</Flexbox>
|
|
78
79
|
);
|
|
79
80
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ActionIcon } from '@lobehub/ui';
|
|
2
|
-
import {
|
|
2
|
+
import { Settings2 } from 'lucide-react';
|
|
3
3
|
import { memo, useState } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
|
|
@@ -19,7 +19,7 @@ const PluginSettings = memo<{ identifier: string }>(({ identifier }) => {
|
|
|
19
19
|
return (
|
|
20
20
|
<>
|
|
21
21
|
<ActionIcon
|
|
22
|
-
icon={
|
|
22
|
+
icon={Settings2}
|
|
23
23
|
onClick={() => {
|
|
24
24
|
setOpen(true);
|
|
25
25
|
}}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Icon, Modal,
|
|
2
|
-
import { Button, Empty } from 'antd';
|
|
1
|
+
import { Icon, Modal, SearchBar } from '@lobehub/ui';
|
|
2
|
+
import { Button, Empty, Segmented } from 'antd';
|
|
3
|
+
import { createStyles } from 'antd-style';
|
|
3
4
|
import isEqual from 'fast-deep-equal';
|
|
4
5
|
import { ServerCrash } from 'lucide-react';
|
|
5
|
-
import { memo } from 'react';
|
|
6
|
+
import { memo, useState } from 'react';
|
|
6
7
|
import { useTranslation } from 'react-i18next';
|
|
7
8
|
import { Center, Flexbox } from 'react-layout-kit';
|
|
8
9
|
|
|
@@ -13,13 +14,24 @@ import { pluginStoreSelectors } from '@/store/tool/selectors';
|
|
|
13
14
|
import Loading from './Loading';
|
|
14
15
|
import PluginItem from './PluginItem';
|
|
15
16
|
|
|
17
|
+
const useStyles = createStyles(({ css, token }) => ({
|
|
18
|
+
header: css`
|
|
19
|
+
color: ${token.colorTextDescription};
|
|
20
|
+
|
|
21
|
+
> div {
|
|
22
|
+
flex: 1;
|
|
23
|
+
}
|
|
24
|
+
`,
|
|
25
|
+
}));
|
|
26
|
+
|
|
16
27
|
interface PluginStoreProps {
|
|
17
28
|
open?: boolean;
|
|
18
29
|
setOpen: (open: boolean) => void;
|
|
19
30
|
}
|
|
20
31
|
export const PluginStore = memo<PluginStoreProps>(({ setOpen, open }) => {
|
|
32
|
+
const [keywords, setKeywords] = useState<string>();
|
|
21
33
|
const { t } = useTranslation('plugin');
|
|
22
|
-
|
|
34
|
+
const { styles } = useStyles();
|
|
23
35
|
const [listType, useFetchPluginList, installPlugins] = useToolStore((s) => [
|
|
24
36
|
s.listType,
|
|
25
37
|
s.useFetchPluginStore,
|
|
@@ -43,28 +55,19 @@ export const PluginStore = memo<PluginStoreProps>(({ setOpen, open }) => {
|
|
|
43
55
|
<MobilePadding>
|
|
44
56
|
<Center>
|
|
45
57
|
<Flexbox gap={24} width={'100%'}>
|
|
46
|
-
<Flexbox align={'center'} horizontal justify={'space-between'}>
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
items={[
|
|
50
|
-
{ key: 'all', label: t('store.tabs.all') },
|
|
51
|
-
{ key: 'installed', label: t('store.tabs.installed') },
|
|
52
|
-
]}
|
|
58
|
+
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'}>
|
|
59
|
+
<Segmented
|
|
60
|
+
block
|
|
53
61
|
onChange={(v) => {
|
|
54
62
|
useToolStore.setState({ listType: v as any });
|
|
55
63
|
}}
|
|
64
|
+
options={[
|
|
65
|
+
{ label: t('store.tabs.all'), value: 'all' },
|
|
66
|
+
{ label: t('store.tabs.installed'), value: 'installed' },
|
|
67
|
+
]}
|
|
68
|
+
style={{ flex: 1 }}
|
|
69
|
+
value={listType}
|
|
56
70
|
/>
|
|
57
|
-
<Flexbox gap={8} horizontal>
|
|
58
|
-
{listType === 'all' && (
|
|
59
|
-
<Button
|
|
60
|
-
onClick={() => {
|
|
61
|
-
installPlugins(pluginStoreList.map((item) => item.identifier));
|
|
62
|
-
}}
|
|
63
|
-
>
|
|
64
|
-
{t('store.installAllPlugins')}
|
|
65
|
-
</Button>
|
|
66
|
-
)}
|
|
67
|
-
</Flexbox>
|
|
68
71
|
</Flexbox>
|
|
69
72
|
{isLoading ? (
|
|
70
73
|
<Loading />
|
|
@@ -83,7 +86,37 @@ export const PluginStore = memo<PluginStoreProps>(({ setOpen, open }) => {
|
|
|
83
86
|
)}
|
|
84
87
|
</Center>
|
|
85
88
|
) : (
|
|
86
|
-
|
|
89
|
+
<>
|
|
90
|
+
<Flexbox className={styles.header} gap={8} horizontal>
|
|
91
|
+
<SearchBar
|
|
92
|
+
allowClear
|
|
93
|
+
onChange={(e) => setKeywords(e.target.value)}
|
|
94
|
+
placeholder={t('store.placeholder')}
|
|
95
|
+
type={'block'}
|
|
96
|
+
value={keywords}
|
|
97
|
+
/>
|
|
98
|
+
{listType === 'all' && (
|
|
99
|
+
<Button
|
|
100
|
+
onClick={() => {
|
|
101
|
+
installPlugins(pluginStoreList.map((item) => item.identifier));
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
{t('store.installAllPlugins')}
|
|
105
|
+
</Button>
|
|
106
|
+
)}
|
|
107
|
+
</Flexbox>
|
|
108
|
+
|
|
109
|
+
{pluginStoreList
|
|
110
|
+
.filter((item) =>
|
|
111
|
+
[item.meta.title, item.meta.description, item.author, ...(item.meta.tags || [])]
|
|
112
|
+
.join('')
|
|
113
|
+
.toLowerCase()
|
|
114
|
+
.includes((keywords || '')?.toLowerCase()),
|
|
115
|
+
)
|
|
116
|
+
.map((item) => (
|
|
117
|
+
<PluginItem key={item.identifier} {...item} />
|
|
118
|
+
))}
|
|
119
|
+
</>
|
|
87
120
|
)}
|
|
88
121
|
</Flexbox>
|
|
89
122
|
</Center>
|
|
@@ -15,7 +15,7 @@ const InnerLocale = memo<LocaleLayoutProps>(({ children, lang }) => {
|
|
|
15
15
|
const { data: locale } = useSWR(
|
|
16
16
|
lang,
|
|
17
17
|
async () =>
|
|
18
|
-
await import(`antd/locale/${lang?.includes('-') ? lang?.replace('-', '_') : '
|
|
18
|
+
await import(`antd/locale/${lang?.includes('-') ? lang?.replace('-', '_') : 'en_US'}.js`),
|
|
19
19
|
{ revalidateOnFocus: false },
|
|
20
20
|
);
|
|
21
21
|
const [i18n] = useState(createI18nNext(lang));
|