@lobehub/chat 0.111.1 → 0.111.3
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 +58 -0
- package/docs/Development-Guide/index.zh-CN.md +1 -1
- package/docs/Plugin-Development.md +1 -1
- package/docs/Plugin-Development.zh-CN.md +1 -1
- 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/chat.json +1 -1
- package/locales/zh_CN/plugin.json +1 -0
- package/locales/zh_CN/setting.json +2 -2
- 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/AgentSetting/AgentConfig/index.tsx +1 -1
- 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/chat.ts +1 -1
- package/src/locales/default/plugin.ts +1 -0
- package/src/locales/default/setting.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.111.3](https://github.com/lobehub/lobe-chat/compare/v0.111.2...v0.111.3)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-12-14**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Fix the history-count text.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Fix the history-count text, closes [#615](https://github.com/lobehub/lobe-chat/issues/615) ([4db1cef](https://github.com/lobehub/lobe-chat/commit/4db1cef))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
### [Version 0.111.2](https://github.com/lobehub/lobe-chat/compare/v0.111.1...v0.111.2)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2023-12-13**</sup>
|
|
33
|
+
|
|
34
|
+
#### 🐛 Bug Fixes
|
|
35
|
+
|
|
36
|
+
- **misc**: Change topic-deletion hotkey.
|
|
37
|
+
|
|
38
|
+
#### 💄 Styles
|
|
39
|
+
|
|
40
|
+
- **misc**: Fix image display in safari (fix.
|
|
41
|
+
|
|
42
|
+
<br/>
|
|
43
|
+
|
|
44
|
+
<details>
|
|
45
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
46
|
+
|
|
47
|
+
#### What's fixed
|
|
48
|
+
|
|
49
|
+
- **misc**: Change topic-deletion hotkey, closes [#616](https://github.com/lobehub/lobe-chat/issues/616) ([912ff45](https://github.com/lobehub/lobe-chat/commit/912ff45))
|
|
50
|
+
|
|
51
|
+
#### Styles
|
|
52
|
+
|
|
53
|
+
- **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))
|
|
54
|
+
|
|
55
|
+
</details>
|
|
56
|
+
|
|
57
|
+
<div align="right">
|
|
58
|
+
|
|
59
|
+
[](#readme-top)
|
|
60
|
+
|
|
61
|
+
</div>
|
|
62
|
+
|
|
5
63
|
### [Version 0.111.1](https://github.com/lobehub/lobe-chat/compare/v0.111.0...v0.111.1)
|
|
6
64
|
|
|
7
65
|
<sup>Released on **2023-12-13**</sup>
|
|
@@ -13,7 +13,7 @@ LobeChat 的核心技术栈如下:
|
|
|
13
13
|
- **路由**:路由管理我们直接使用 [Next.js](https://nextjs.org/) 自身提供的解决方案。
|
|
14
14
|
- **国际化**:我们使用 [i18next](https://www.i18next.com/) 来实现应用的多语言支持。
|
|
15
15
|
- **样式**:我们使用 [antd-style](https://github.com/ant-design/antd-style),这是一款与 Ant Design 配套的 CSS-in-JS 库。
|
|
16
|
-
- **单元测试**:我们使用 [vitest](https://github.com/
|
|
16
|
+
- **单元测试**:我们使用 [vitest](https://github.com/vitest-dev/vitest) 进行单元测试。
|
|
17
17
|
|
|
18
18
|
## 文件夹目录架构
|
|
19
19
|
|
|
@@ -274,7 +274,7 @@ If you want more people to use your plugin, you are welcome to submit it for rev
|
|
|
274
274
|
- **📘 Pluging SDK Docs**: <https://chat-plugin-sdk.lobehub.com>
|
|
275
275
|
- **🚀 chat-plugin-template**: <https://github.com/lobehub/chat-plugin-template>
|
|
276
276
|
- **🧩 chat-plugin-sdk**: <https://github.com/lobehub/chat-plugin-sdk>
|
|
277
|
-
- **🚪 chat-plugin-sdk**: <https://github.com/lobehub/chat-
|
|
277
|
+
- **🚪 chat-plugin-sdk**: <https://github.com/lobehub/chat-plugins-gateway>
|
|
278
278
|
- **🏪 lobe-chat-plugins**: <https://github.com/lobehub/lobe-chat-plugins>
|
|
279
279
|
|
|
280
280
|
<!-- LINK GROUP -->
|
|
@@ -273,7 +273,7 @@ export default Render;
|
|
|
273
273
|
- **📘 Pluging SDK 文档**: <https://chat-plugin-sdk.lobehub.com>
|
|
274
274
|
- **🚀 chat-plugin-template**: <https://github.com/lobehub/chat-plugin-template>
|
|
275
275
|
- **🧩 chat-plugin-sdk**: <https://github.com/lobehub/chat-plugin-sdk>
|
|
276
|
-
- **🚪 chat-plugin-gateway**: <https://github.com/lobehub/chat-
|
|
276
|
+
- **🚪 chat-plugin-gateway**: <https://github.com/lobehub/chat-plugins-gateway>
|
|
277
277
|
- **🏪 lobe-chat-plugins**: <https://github.com/lobehub/lobe-chat-plugins>
|
|
278
278
|
|
|
279
279
|
<!-- LINK GROUP -->
|
package/locales/zh_CN/chat.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.111.
|
|
3
|
+
"version": "0.111.3",
|
|
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
|
@@ -84,7 +84,7 @@ const AgentConfig = memo(() => {
|
|
|
84
84
|
valuePropName: 'checked',
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
|
-
children: <SliderWithInput max={32} min={
|
|
87
|
+
children: <SliderWithInput max={32} min={1} />,
|
|
88
88
|
desc: t('settingChat.historyCount.desc'),
|
|
89
89
|
divider: false,
|
|
90
90
|
hidden: !config.enableHistoryCount,
|
|
@@ -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));
|