@lobehub/chat 1.52.10 → 1.52.12
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 +50 -0
- package/changelog/v1.json +18 -0
- package/docs/self-hosting/environment-variables/auth.zh-CN.mdx +2 -2
- package/package.json +1 -1
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/AgentsSuggest.tsx +3 -3
- package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/DefaultMode.tsx +1 -1
- package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +3 -3
- package/src/app/[variants]/(main)/settings/common/features/Theme/index.tsx +4 -5
- package/src/chains/__tests__/summaryAgentName.test.ts +2 -2
- package/src/chains/__tests__/summaryDescription.test.ts +2 -2
- package/src/chains/__tests__/summaryHistory.test.ts +1 -1
- package/src/chains/__tests__/summaryTags.test.ts +2 -2
- package/src/chains/__tests__/summaryTitle.test.ts +2 -2
- package/src/chains/summaryAgentName.ts +1 -1
- package/src/chains/summaryDescription.ts +1 -1
- package/src/chains/summaryTags.ts +1 -1
- package/src/chains/summaryTitle.ts +1 -1
- package/src/const/settings/common.ts +0 -1
- package/src/features/AgentSetting/AgentMeta/AutoGenerateAvatar.tsx +3 -3
- package/src/features/AgentSetting/AgentTTS/index.tsx +4 -4
- package/src/features/ChatInput/STT/browser.tsx +4 -2
- package/src/features/ChatInput/STT/openai.tsx +4 -2
- package/src/features/Conversation/Extras/TTS/index.tsx +3 -3
- package/src/features/PluginDevModal/LocalForm.tsx +3 -3
- package/src/features/Portal/Artifacts/Body/Renderer/index.tsx +5 -1
- package/src/features/User/UserPanel/LangButton.tsx +12 -6
- package/src/hooks/useTTS.ts +4 -2
- package/src/layout/GlobalProvider/AppTheme.tsx +1 -1
- package/src/middleware.ts +3 -4
- package/src/services/__tests__/assistant.test.ts +2 -2
- package/src/services/__tests__/tool.test.ts +2 -2
- package/src/services/assistant.ts +1 -1
- package/src/services/tool.ts +1 -1
- package/src/store/global/{action.ts → actions/general.ts} +11 -62
- package/src/store/global/actions/workspacePane.ts +73 -0
- package/src/store/global/helpers.ts +6 -0
- package/src/store/global/initialState.ts +2 -0
- package/src/store/global/selectors/general.test.ts +18 -0
- package/src/store/global/selectors/general.ts +25 -0
- package/src/store/global/selectors/index.ts +2 -0
- package/src/store/global/{selectors.ts → selectors/systemStatus.ts} +2 -2
- package/src/store/global/store.ts +11 -3
- package/src/store/user/slices/common/action.test.ts +3 -15
- package/src/store/user/slices/common/action.ts +0 -8
- package/src/store/user/slices/settings/action.ts +0 -8
- package/src/store/user/slices/settings/selectors/general.test.ts +0 -14
- package/src/store/user/slices/settings/selectors/general.ts +0 -19
- package/src/types/user/settings/general.ts +0 -3
- package/src/utils/client/cookie.test.ts +85 -0
- package/src/utils/client/cookie.ts +22 -0
- package/src/utils/client/switchLang.ts +5 -0
- package/src/store/user/helpers.ts +0 -9
- package/src/utils/cookie.ts +0 -10
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,56 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.52.12](https://github.com/lobehub/lobe-chat/compare/v1.52.11...v1.52.12)
|
6
|
+
|
7
|
+
<sup>Released on **2025-02-10**</sup>
|
8
|
+
|
9
|
+
#### 🐛 Bug Fixes
|
10
|
+
|
11
|
+
- **misc**: Fix language incorrect on page hydration.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### What's fixed
|
19
|
+
|
20
|
+
- **misc**: Fix language incorrect on page hydration, closes [#5970](https://github.com/lobehub/lobe-chat/issues/5970) ([91912cf](https://github.com/lobehub/lobe-chat/commit/91912cf))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.52.11](https://github.com/lobehub/lobe-chat/compare/v1.52.10...v1.52.11)
|
31
|
+
|
32
|
+
<sup>Released on **2025-02-10**</sup>
|
33
|
+
|
34
|
+
#### 💄 Styles
|
35
|
+
|
36
|
+
- **misc**: Support Mermaid in Artifacts.
|
37
|
+
|
38
|
+
<br/>
|
39
|
+
|
40
|
+
<details>
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
42
|
+
|
43
|
+
#### Styles
|
44
|
+
|
45
|
+
- **misc**: Support Mermaid in Artifacts, closes [#5947](https://github.com/lobehub/lobe-chat/issues/5947) ([892f961](https://github.com/lobehub/lobe-chat/commit/892f961))
|
46
|
+
|
47
|
+
</details>
|
48
|
+
|
49
|
+
<div align="right">
|
50
|
+
|
51
|
+
[](#readme-top)
|
52
|
+
|
53
|
+
</div>
|
54
|
+
|
5
55
|
### [Version 1.52.10](https://github.com/lobehub/lobe-chat/compare/v1.52.9...v1.52.10)
|
6
56
|
|
7
57
|
<sup>Released on **2025-02-09**</sup>
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"fixes": [
|
5
|
+
"Fix language incorrect on page hydration."
|
6
|
+
]
|
7
|
+
},
|
8
|
+
"date": "2025-02-10",
|
9
|
+
"version": "1.52.12"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"children": {
|
13
|
+
"improvements": [
|
14
|
+
"Support Mermaid in Artifacts."
|
15
|
+
]
|
16
|
+
},
|
17
|
+
"date": "2025-02-10",
|
18
|
+
"version": "1.52.11"
|
19
|
+
},
|
2
20
|
{
|
3
21
|
"children": {},
|
4
22
|
"date": "2025-02-09",
|
@@ -47,7 +47,7 @@ LobeChat 在部署时提供了完善的身份验证服务能力,以下是相
|
|
47
47
|
- 默认值: `-`
|
48
48
|
- 示例: `evCnOJP1UX8FMnXR9Xkj5t0NyFn5p70P`
|
49
49
|
|
50
|
-
#### `
|
50
|
+
#### `AUTH_AUTH0_SECRET`
|
51
51
|
|
52
52
|
- 类型:必选
|
53
53
|
- 描述: Auth0 应用程序的 Client Secret
|
@@ -280,4 +280,4 @@ LobeChat 在部署时提供了完善的身份验证服务能力,以下是相
|
|
280
280
|
- 类型:必选
|
281
281
|
- 描述: Clerk 应用程序的 Secret key。您可以在[这里](https://dashboard.clerk.com)访问,并导航到 API Keys 以查看。
|
282
282
|
- 默认值:`-`
|
283
|
-
- 示例: `sk_test_513Ma0P7IAWM1XMv4waxZjRYRajWTaCfJLjpEO3SD2` (测试环境) / `sk_live_eMMlHjwJvZFUfczFljSKqZdwQtLvmczmsJSNmdrpeZ`(生产环境)
|
283
|
+
- 示例: `sk_test_513Ma0P7IAWM1XMv4waxZjRYRajWTaCfJLjpEO3SD2` (测试环境) / `sk_live_eMMlHjwJvZFUfczFljSKqZdwQtLvmczmsJSNmdrpeZ`(生产环境)
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.52.
|
3
|
+
"version": "1.52.12",
|
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",
|
@@ -12,8 +12,8 @@ import useSWR from 'swr';
|
|
12
12
|
import urlJoin from 'url-join';
|
13
13
|
|
14
14
|
import { assistantService } from '@/services/assistant';
|
15
|
-
import {
|
16
|
-
import {
|
15
|
+
import { useGlobalStore } from '@/store/global';
|
16
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
17
17
|
import { DiscoverAssistantItem } from '@/types/discover';
|
18
18
|
|
19
19
|
const { Paragraph } = Typography;
|
@@ -60,7 +60,7 @@ const useStyles = createStyles(({ css, token, responsive }) => ({
|
|
60
60
|
|
61
61
|
const AgentsSuggest = memo<{ mobile?: boolean }>(({ mobile }) => {
|
62
62
|
const { t } = useTranslation('welcome');
|
63
|
-
const locale =
|
63
|
+
const locale = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
64
64
|
const [sliceStart, setSliceStart] = useState(0);
|
65
65
|
|
66
66
|
const { data: assistantList, isLoading } = useSWR(
|
package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx
CHANGED
@@ -14,10 +14,10 @@ import { AGENTS_INDEX_GITHUB_ISSUE } from '@/const/url';
|
|
14
14
|
import AgentInfo from '@/features/AgentInfo';
|
15
15
|
import { useAgentStore } from '@/store/agent';
|
16
16
|
import { agentSelectors } from '@/store/agent/selectors';
|
17
|
+
import { useGlobalStore } from '@/store/global';
|
18
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
17
19
|
import { useSessionStore } from '@/store/session';
|
18
20
|
import { sessionMetaSelectors } from '@/store/session/selectors';
|
19
|
-
import { useUserStore } from '@/store/user';
|
20
|
-
import { userGeneralSettingsSelectors } from '@/store/user/selectors';
|
21
21
|
|
22
22
|
const SubmitAgentModal = memo<ModalProps>(({ open, onCancel }) => {
|
23
23
|
const { t } = useTranslation('setting');
|
@@ -25,7 +25,7 @@ const SubmitAgentModal = memo<ModalProps>(({ open, onCancel }) => {
|
|
25
25
|
const systemRole = useAgentStore(agentSelectors.currentAgentSystemRole);
|
26
26
|
const theme = useTheme();
|
27
27
|
const meta = useSessionStore(sessionMetaSelectors.currentAgentMeta, isEqual);
|
28
|
-
const language =
|
28
|
+
const language = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
29
29
|
|
30
30
|
const isMetaPass = Boolean(
|
31
31
|
meta && meta.title && meta.description && (meta.tags as string[])?.length > 0 && meta.avatar,
|
@@ -4,7 +4,6 @@ import { Form, type ItemGroup, SelectWithImg, SliderWithInput } from '@lobehub/u
|
|
4
4
|
import { Select } from 'antd';
|
5
5
|
import isEqual from 'fast-deep-equal';
|
6
6
|
import { Monitor, Moon, Sun } from 'lucide-react';
|
7
|
-
import { useRouter } from 'next/navigation';
|
8
7
|
import { memo } from 'react';
|
9
8
|
import { useTranslation } from 'react-i18next';
|
10
9
|
|
@@ -12,9 +11,9 @@ import { useSyncSettings } from '@/app/[variants]/(main)/settings/hooks/useSyncS
|
|
12
11
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
13
12
|
import { imageUrl } from '@/const/url';
|
14
13
|
import { Locales, localeOptions } from '@/locales/resources';
|
14
|
+
import { useGlobalStore } from '@/store/global';
|
15
15
|
import { useUserStore } from '@/store/user';
|
16
16
|
import { settingsSelectors, userGeneralSettingsSelectors } from '@/store/user/selectors';
|
17
|
-
import { switchLang } from '@/utils/client/switchLang';
|
18
17
|
|
19
18
|
import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from './ThemeSwatches';
|
20
19
|
|
@@ -22,17 +21,17 @@ type SettingItemGroup = ItemGroup;
|
|
22
21
|
|
23
22
|
const Theme = memo(() => {
|
24
23
|
const { t } = useTranslation('setting');
|
25
|
-
|
24
|
+
|
26
25
|
const [form] = Form.useForm();
|
27
26
|
const settings = useUserStore(settingsSelectors.currentSettings, isEqual);
|
28
27
|
const themeMode = useUserStore(userGeneralSettingsSelectors.currentThemeMode);
|
29
28
|
const [setThemeMode, setSettings] = useUserStore((s) => [s.switchThemeMode, s.setSettings]);
|
30
29
|
|
31
30
|
useSyncSettings(form);
|
31
|
+
const [switchLocale] = useGlobalStore((s) => [s.switchLocale]);
|
32
32
|
|
33
33
|
const handleLangChange = (value: Locales) => {
|
34
|
-
|
35
|
-
router.refresh();
|
34
|
+
switchLocale(value);
|
36
35
|
};
|
37
36
|
|
38
37
|
const theme: SettingItemGroup = {
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { Mock, describe, expect, it } from 'vitest';
|
2
2
|
|
3
|
-
import { globalHelpers } from '@/store/
|
3
|
+
import { globalHelpers } from '@/store/global/helpers';
|
4
4
|
|
5
5
|
import { chainSummaryAgentName } from '../summaryAgentName';
|
6
6
|
|
7
7
|
// Mock the getCurrentLanguage function
|
8
|
-
vi.mock('@/store/
|
8
|
+
vi.mock('@/store/global/helpers', () => ({
|
9
9
|
globalHelpers: {
|
10
10
|
getCurrentLanguage: vi.fn(),
|
11
11
|
},
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { Mock, describe, expect, it, vi } from 'vitest';
|
2
2
|
|
3
|
-
import { globalHelpers } from '@/store/
|
3
|
+
import { globalHelpers } from '@/store/global/helpers';
|
4
4
|
|
5
5
|
import { chainSummaryDescription } from '../summaryDescription';
|
6
6
|
|
7
7
|
// Mock the globalHelpers.getCurrentLanguage function
|
8
|
-
vi.mock('@/store/
|
8
|
+
vi.mock('@/store/global/helpers', () => ({
|
9
9
|
globalHelpers: {
|
10
10
|
getCurrentLanguage: vi.fn(() => 'en-US'),
|
11
11
|
},
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Mock, describe, expect, it, vi } from 'vitest';
|
2
2
|
|
3
3
|
import { chatHelpers } from '@/store/chat/helpers';
|
4
|
-
import { globalHelpers } from '@/store/
|
4
|
+
import { globalHelpers } from '@/store/global/helpers';
|
5
5
|
import { ChatMessage } from '@/types/message';
|
6
6
|
import { OpenAIChatMessage } from '@/types/openai/chat';
|
7
7
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { Mock, describe, expect, it } from 'vitest';
|
2
2
|
|
3
|
-
import { globalHelpers } from '@/store/
|
3
|
+
import { globalHelpers } from '@/store/global/helpers';
|
4
4
|
|
5
5
|
import { chainSummaryTags } from '../summaryTags';
|
6
6
|
|
7
7
|
// Mock the getCurrentLanguage function
|
8
|
-
vi.mock('@/store/
|
8
|
+
vi.mock('@/store/global/helpers', () => ({
|
9
9
|
globalHelpers: {
|
10
10
|
getCurrentLanguage: vi.fn(),
|
11
11
|
},
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { Mock, describe, expect, it, vi } from 'vitest';
|
2
2
|
|
3
3
|
import { chatHelpers } from '@/store/chat/helpers';
|
4
|
-
import { globalHelpers } from '@/store/
|
4
|
+
import { globalHelpers } from '@/store/global/helpers';
|
5
5
|
import { OpenAIChatMessage } from '@/types/openai/chat';
|
6
6
|
|
7
7
|
import { chainSummaryTitle } from '../summaryTitle';
|
8
8
|
|
9
9
|
// Mock the getCurrentLanguage function
|
10
|
-
vi.mock('@/store/
|
10
|
+
vi.mock('@/store/global/helpers', () => ({
|
11
11
|
globalHelpers: {
|
12
12
|
getCurrentLanguage: vi.fn(),
|
13
13
|
},
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { globalHelpers } from '@/store/
|
1
|
+
import { globalHelpers } from '@/store/global/helpers';
|
2
2
|
import { ChatStreamPayload, OpenAIChatMessage } from '@/types/openai/chat';
|
3
3
|
|
4
4
|
export const chainSummaryTitle = (messages: OpenAIChatMessage[]): Partial<ChatStreamPayload> => {
|
@@ -6,8 +6,8 @@ import { memo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
8
8
|
|
9
|
-
import {
|
10
|
-
import {
|
9
|
+
import { useGlobalStore } from '@/store/global';
|
10
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
11
11
|
|
12
12
|
const EmojiPicker = dynamic(() => import('@lobehub/ui/es/EmojiPicker'), { ssr: false });
|
13
13
|
|
@@ -24,7 +24,7 @@ const AutoGenerateAvatar = memo<AutoGenerateAvatarProps>(
|
|
24
24
|
({ loading, background, value, onChange, onGenerate, canAutoGenerate }) => {
|
25
25
|
const { t } = useTranslation('common');
|
26
26
|
const theme = useTheme();
|
27
|
-
const locale =
|
27
|
+
const locale = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
28
28
|
|
29
29
|
return (
|
30
30
|
<Flexbox>
|
@@ -9,8 +9,8 @@ import { memo, useMemo } from 'react';
|
|
9
9
|
import { useTranslation } from 'react-i18next';
|
10
10
|
|
11
11
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
12
|
-
import {
|
13
|
-
import {
|
12
|
+
import { useGlobalStore } from '@/store/global';
|
13
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
14
14
|
|
15
15
|
import { useStore } from '../store';
|
16
16
|
import { useAgentSyncSettings } from '../useSyncAgemtSettings';
|
@@ -23,8 +23,8 @@ const { openaiVoiceOptions, localeOptions } = VoiceList;
|
|
23
23
|
const AgentTTS = memo(() => {
|
24
24
|
const { t } = useTranslation('setting');
|
25
25
|
const [form] = Form.useForm();
|
26
|
-
const voiceList =
|
27
|
-
const locale =
|
26
|
+
const voiceList = useGlobalStore((s) => {
|
27
|
+
const locale = globalGeneralSelectors.currentLanguage(s);
|
28
28
|
return (all?: boolean) => new VoiceList(all ? undefined : locale);
|
29
29
|
});
|
30
30
|
const [showAllLocaleVoice, ttsService, updateConfig] = useStore((s) => [
|
@@ -8,8 +8,10 @@ import { useAgentStore } from '@/store/agent';
|
|
8
8
|
import { agentSelectors } from '@/store/agent/slices/chat';
|
9
9
|
import { useChatStore } from '@/store/chat';
|
10
10
|
import { chatSelectors } from '@/store/chat/selectors';
|
11
|
+
import { useGlobalStore } from '@/store/global';
|
12
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
11
13
|
import { useUserStore } from '@/store/user';
|
12
|
-
import { settingsSelectors
|
14
|
+
import { settingsSelectors } from '@/store/user/selectors';
|
13
15
|
import { ChatMessageError } from '@/types/message';
|
14
16
|
import { getMessageError } from '@/utils/fetch';
|
15
17
|
|
@@ -22,7 +24,7 @@ interface STTConfig extends SWRConfiguration {
|
|
22
24
|
const useBrowserSTT = (config: STTConfig) => {
|
23
25
|
const ttsSettings = useUserStore(settingsSelectors.currentTTS, isEqual);
|
24
26
|
const ttsAgentSettings = useAgentStore(agentSelectors.currentAgentTTS, isEqual);
|
25
|
-
const locale =
|
27
|
+
const locale = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
26
28
|
|
27
29
|
const autoStop = ttsSettings.sttAutoStop;
|
28
30
|
const sttLocale =
|
@@ -11,8 +11,10 @@ import { useAgentStore } from '@/store/agent';
|
|
11
11
|
import { agentSelectors } from '@/store/agent/selectors';
|
12
12
|
import { useChatStore } from '@/store/chat';
|
13
13
|
import { chatSelectors } from '@/store/chat/slices/message/selectors';
|
14
|
+
import { useGlobalStore } from '@/store/global';
|
15
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
14
16
|
import { useUserStore } from '@/store/user';
|
15
|
-
import { settingsSelectors
|
17
|
+
import { settingsSelectors } from '@/store/user/selectors';
|
16
18
|
import { ChatMessageError } from '@/types/message';
|
17
19
|
import { getMessageError } from '@/utils/fetch';
|
18
20
|
|
@@ -25,7 +27,7 @@ interface STTConfig extends SWRConfiguration {
|
|
25
27
|
const useOpenaiSTT = (config: STTConfig) => {
|
26
28
|
const ttsSettings = useUserStore(settingsSelectors.currentTTS, isEqual);
|
27
29
|
const ttsAgentSettings = useAgentStore(agentSelectors.currentAgentTTS, isEqual);
|
28
|
-
const locale =
|
30
|
+
const locale = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
29
31
|
|
30
32
|
const autoStop = ttsSettings.sttAutoStop;
|
31
33
|
const sttLocale =
|
@@ -3,8 +3,8 @@ import { Md5 } from 'ts-md5';
|
|
3
3
|
|
4
4
|
import { useAgentStore } from '@/store/agent';
|
5
5
|
import { agentSelectors } from '@/store/agent/slices/chat';
|
6
|
-
import {
|
7
|
-
import {
|
6
|
+
import { useGlobalStore } from '@/store/global';
|
7
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
8
8
|
|
9
9
|
import FilePlayer from './FilePlayer';
|
10
10
|
import InitPlayer, { TTSProps } from './InitPlayer';
|
@@ -12,7 +12,7 @@ import InitPlayer, { TTSProps } from './InitPlayer';
|
|
12
12
|
const TTS = memo<TTSProps>(
|
13
13
|
(props) => {
|
14
14
|
const { file, voice, content, contentMd5 } = props;
|
15
|
-
const lang =
|
15
|
+
const lang = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
16
16
|
const currentVoice = useAgentStore(agentSelectors.currentAgentTTSVoice(lang));
|
17
17
|
|
18
18
|
const md5 = useMemo(() => Md5.hashStr(content).toString(), [content]);
|
@@ -4,16 +4,16 @@ import dynamic from 'next/dynamic';
|
|
4
4
|
import { memo } from 'react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
6
6
|
|
7
|
+
import { useGlobalStore } from '@/store/global';
|
8
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
7
9
|
import { useToolStore } from '@/store/tool';
|
8
10
|
import { pluginSelectors } from '@/store/tool/selectors';
|
9
|
-
import { useUserStore } from '@/store/user';
|
10
|
-
import { userGeneralSettingsSelectors } from '@/store/user/selectors';
|
11
11
|
|
12
12
|
const EmojiPicker = dynamic(() => import('@lobehub/ui/es/EmojiPicker'), { ssr: false });
|
13
13
|
|
14
14
|
const LocalForm = memo<{ form: FormInstance; mode?: 'edit' | 'create' }>(({ form, mode }) => {
|
15
15
|
const isEditMode = mode === 'edit';
|
16
|
-
const locale =
|
16
|
+
const locale = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
17
17
|
const { t } = useTranslation('plugin');
|
18
18
|
|
19
19
|
const pluginIds = useToolStore(pluginSelectors.storeAndInstallPluginsIdList);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Markdown } from '@lobehub/ui';
|
1
|
+
import { Markdown, Mermaid } from '@lobehub/ui';
|
2
2
|
import dynamic from 'next/dynamic';
|
3
3
|
import { memo } from 'react';
|
4
4
|
|
@@ -17,6 +17,10 @@ const Renderer = memo<{ content: string; type?: string }>(({ content, type }) =>
|
|
17
17
|
return <SVGRender content={content} />;
|
18
18
|
}
|
19
19
|
|
20
|
+
case 'application/lobe.artifacts.mermaid': {
|
21
|
+
return <Mermaid type={'pure'}>{content}</Mermaid>;
|
22
|
+
}
|
23
|
+
|
20
24
|
case 'text/markdown': {
|
21
25
|
return <Markdown style={{ overflow: 'auto' }}>{content}</Markdown>;
|
22
26
|
}
|
@@ -7,16 +7,22 @@ import { useTranslation } from 'react-i18next';
|
|
7
7
|
|
8
8
|
import Menu, { type MenuProps } from '@/components/Menu';
|
9
9
|
import { localeOptions } from '@/locales/resources';
|
10
|
-
import {
|
11
|
-
import {
|
10
|
+
import { useGlobalStore } from '@/store/global';
|
11
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
12
|
+
import { LocaleMode } from '@/types/locale';
|
12
13
|
|
13
14
|
const LangButton = memo<{ placement?: PopoverProps['placement'] }>(({ placement = 'right' }) => {
|
14
15
|
const theme = useTheme();
|
15
|
-
|
16
|
-
|
16
|
+
|
17
|
+
const [language, switchLocale] = useGlobalStore((s) => [
|
18
|
+
globalGeneralSelectors.language(s),
|
17
19
|
s.switchLocale,
|
18
20
|
]);
|
19
21
|
|
22
|
+
const handleLangChange = (value: LocaleMode) => {
|
23
|
+
switchLocale(value);
|
24
|
+
};
|
25
|
+
|
20
26
|
const { t } = useTranslation('setting');
|
21
27
|
|
22
28
|
const items: MenuProps['items'] = useMemo(
|
@@ -24,12 +30,12 @@ const LangButton = memo<{ placement?: PopoverProps['placement'] }>(({ placement
|
|
24
30
|
{
|
25
31
|
key: 'auto',
|
26
32
|
label: t('settingTheme.lang.autoMode'),
|
27
|
-
onClick: () =>
|
33
|
+
onClick: () => handleLangChange('auto'),
|
28
34
|
},
|
29
35
|
...localeOptions.map((item) => ({
|
30
36
|
key: item.value,
|
31
37
|
label: item.label,
|
32
|
-
onClick: () =>
|
38
|
+
onClick: () => handleLangChange(item.value),
|
33
39
|
})),
|
34
40
|
],
|
35
41
|
[t],
|
package/src/hooks/useTTS.ts
CHANGED
@@ -13,8 +13,10 @@ import { createHeaderWithOpenAI } from '@/services/_header';
|
|
13
13
|
import { API_ENDPOINTS } from '@/services/_url';
|
14
14
|
import { useAgentStore } from '@/store/agent';
|
15
15
|
import { agentSelectors } from '@/store/agent/slices/chat';
|
16
|
+
import { useGlobalStore } from '@/store/global';
|
17
|
+
import { globalGeneralSelectors } from '@/store/global/selectors';
|
16
18
|
import { useUserStore } from '@/store/user';
|
17
|
-
import { settingsSelectors
|
19
|
+
import { settingsSelectors } from '@/store/user/selectors';
|
18
20
|
import { TTSServer } from '@/types/agent';
|
19
21
|
|
20
22
|
interface TTSConfig extends TTSOptions {
|
@@ -26,7 +28,7 @@ interface TTSConfig extends TTSOptions {
|
|
26
28
|
export const useTTS = (content: string, config?: TTSConfig) => {
|
27
29
|
const ttsSettings = useUserStore(settingsSelectors.currentTTS, isEqual);
|
28
30
|
const ttsAgentSettings = useAgentStore(agentSelectors.currentAgentTTS, isEqual);
|
29
|
-
const lang =
|
31
|
+
const lang = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
30
32
|
const voice = useAgentStore(agentSelectors.currentAgentTTSVoice(lang));
|
31
33
|
let useSelectedTTS;
|
32
34
|
let options: any = {};
|
@@ -22,7 +22,7 @@ import {
|
|
22
22
|
import { useUserStore } from '@/store/user';
|
23
23
|
import { userGeneralSettingsSelectors } from '@/store/user/selectors';
|
24
24
|
import { GlobalStyle } from '@/styles';
|
25
|
-
import { setCookie } from '@/utils/cookie';
|
25
|
+
import { setCookie } from '@/utils/client/cookie';
|
26
26
|
|
27
27
|
const useStyles = createStyles(({ css, token }) => ({
|
28
28
|
app: css`
|
package/src/middleware.ts
CHANGED
@@ -5,6 +5,7 @@ import urlJoin from 'url-join';
|
|
5
5
|
|
6
6
|
import { appEnv } from '@/config/app';
|
7
7
|
import { authEnv } from '@/config/auth';
|
8
|
+
import { LOBE_LOCALE_COOKIE } from '@/const/locale';
|
8
9
|
import { LOBE_THEME_APPEARANCE } from '@/const/theme';
|
9
10
|
import NextAuthEdge from '@/libs/next-auth/edge';
|
10
11
|
import { Locales } from '@/locales/resources';
|
@@ -54,10 +55,8 @@ const defaultMiddleware = (request: NextRequest) => {
|
|
54
55
|
|
55
56
|
// if it's a new user, there's no cookie
|
56
57
|
// So we need to use the fallback language parsed by accept-language
|
57
|
-
const
|
58
|
-
|
59
|
-
// request.cookies.get(LOBE_LOCALE_COOKIE)?.value ||
|
60
|
-
// browserLanguage;
|
58
|
+
const browserLanguage = parseBrowserLanguage(request.headers);
|
59
|
+
const locale = (request.cookies.get(LOBE_LOCALE_COOKIE)?.value || browserLanguage) as Locales;
|
61
60
|
|
62
61
|
const ua = request.headers.get('user-agent');
|
63
62
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
|
2
2
|
|
3
|
-
import { globalHelpers } from '@/store/
|
3
|
+
import { globalHelpers } from '@/store/global/helpers';
|
4
4
|
|
5
5
|
import { assistantService } from '../assistant';
|
6
6
|
|
7
7
|
// Mocking modules and functions
|
8
8
|
|
9
|
-
vi.mock('@/store/
|
9
|
+
vi.mock('@/store/global/helpers', () => ({
|
10
10
|
globalHelpers: {
|
11
11
|
getCurrentLanguage: vi.fn(),
|
12
12
|
},
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
|
2
2
|
|
3
|
-
import { globalHelpers } from '@/store/
|
3
|
+
import { globalHelpers } from '@/store/global/helpers';
|
4
4
|
|
5
5
|
import { toolService } from '../tool';
|
6
6
|
import openAPIV3 from './openai/OpenAPI_V3.json';
|
@@ -8,7 +8,7 @@ import OpenAIPlugin from './openai/plugin.json';
|
|
8
8
|
|
9
9
|
// Mocking modules and functions
|
10
10
|
|
11
|
-
vi.mock('@/store/
|
11
|
+
vi.mock('@/store/global/helpers', () => ({
|
12
12
|
globalHelpers: {
|
13
13
|
getCurrentLanguage: vi.fn(),
|
14
14
|
},
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { cloneDeep, merge } from 'lodash-es';
|
2
2
|
|
3
3
|
import { DEFAULT_DISCOVER_ASSISTANT_ITEM } from '@/const/discover';
|
4
|
-
import { globalHelpers } from '@/store/
|
4
|
+
import { globalHelpers } from '@/store/global/helpers';
|
5
5
|
import { DiscoverAssistantItem } from '@/types/discover';
|
6
6
|
|
7
7
|
import { API_ENDPOINTS } from './_url';
|
package/src/services/tool.ts
CHANGED