@lobehub/chat 1.86.1 → 1.87.0

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/changelog/v1.json +12 -0
  3. package/locales/ar/setting.json +43 -31
  4. package/locales/bg-BG/setting.json +43 -31
  5. package/locales/de-DE/setting.json +43 -31
  6. package/locales/en-US/setting.json +43 -31
  7. package/locales/es-ES/setting.json +43 -31
  8. package/locales/fa-IR/setting.json +43 -31
  9. package/locales/fr-FR/setting.json +43 -31
  10. package/locales/it-IT/setting.json +43 -31
  11. package/locales/ja-JP/setting.json +43 -31
  12. package/locales/ko-KR/setting.json +43 -31
  13. package/locales/nl-NL/setting.json +43 -31
  14. package/locales/pl-PL/setting.json +43 -31
  15. package/locales/pt-BR/setting.json +43 -31
  16. package/locales/ru-RU/setting.json +43 -31
  17. package/locales/tr-TR/setting.json +43 -31
  18. package/locales/vi-VN/setting.json +43 -31
  19. package/locales/zh-CN/setting.json +43 -31
  20. package/locales/zh-TW/setting.json +43 -31
  21. package/package.json +3 -3
  22. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/WelcomeMessage.tsx +1 -1
  23. package/src/app/[variants]/(main)/settings/agent/index.tsx +8 -2
  24. package/src/app/[variants]/(main)/settings/common/features/Appearance/Preview.tsx +298 -0
  25. package/src/app/[variants]/(main)/settings/common/features/{Theme → Appearance}/ThemeSwatches/ThemeSwatchesNeutral.tsx +6 -11
  26. package/src/app/[variants]/(main)/settings/common/features/{Theme → Appearance}/ThemeSwatches/ThemeSwatchesPrimary.tsx +6 -10
  27. package/src/app/[variants]/(main)/settings/common/features/Appearance/index.tsx +67 -0
  28. package/src/app/[variants]/(main)/settings/common/features/ChatAppearance/ChatPreview.tsx +35 -0
  29. package/src/app/[variants]/(main)/settings/common/features/ChatAppearance/HighlighterPreview.tsx +55 -0
  30. package/src/app/[variants]/(main)/settings/common/features/ChatAppearance/MermaidPreview.tsx +51 -0
  31. package/src/app/[variants]/(main)/settings/common/features/ChatAppearance/index.tsx +128 -0
  32. package/src/app/[variants]/(main)/settings/common/features/Common.tsx +74 -42
  33. package/src/app/[variants]/(main)/settings/common/index.tsx +4 -2
  34. package/src/app/[variants]/(main)/settings/hotkey/features/{HotkeySetting.tsx → Conversation.tsx} +19 -18
  35. package/src/app/[variants]/(main)/settings/hotkey/features/Essential.tsx +88 -0
  36. package/src/app/[variants]/(main)/settings/hotkey/page.tsx +8 -2
  37. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/index.tsx +1 -1
  38. package/src/app/[variants]/(main)/settings/storage/Advanced.tsx +26 -0
  39. package/src/app/[variants]/(main)/settings/system-agent/features/createForm.tsx +37 -22
  40. package/src/app/[variants]/(main)/settings/tts/features/OpenAI.tsx +20 -10
  41. package/src/app/[variants]/(main)/settings/tts/features/STT.tsx +20 -11
  42. package/src/const/settings/common.ts +2 -0
  43. package/src/features/AgentSetting/AgentTTS/index.tsx +1 -1
  44. package/src/features/ChatItem/index.tsx +35 -0
  45. package/src/features/Conversation/components/ChatItem/index.tsx +2 -6
  46. package/src/features/User/UserPanel/LangButton.tsx +1 -1
  47. package/src/features/User/UserPanel/ThemeButton.tsx +3 -3
  48. package/src/libs/model-runtime/{AgentRuntime.test.ts → ModelRuntime.test.ts} +1 -1
  49. package/src/libs/model-runtime/{AgentRuntime.ts → ModelRuntime.ts} +3 -3
  50. package/src/libs/model-runtime/index.ts +1 -1
  51. package/src/libs/oidc-provider/config.ts +1 -1
  52. package/src/locales/default/setting.ts +45 -31
  53. package/src/store/electron/initialState.ts +1 -1
  54. package/src/store/electron/selectors/__tests__/desktopState.test.ts +55 -0
  55. package/src/store/global/selectors/systemStatus.ts +2 -0
  56. package/src/store/user/slices/settings/selectors/general.test.ts +29 -1
  57. package/src/store/user/slices/settings/selectors/general.ts +4 -0
  58. package/src/types/user/settings/general.ts +3 -1
  59. package/src/app/[variants]/(main)/settings/common/features/Theme/index.tsx +0 -146
  60. /package/src/app/[variants]/(main)/settings/common/features/{Theme → Appearance}/ThemeSwatches/index.ts +0 -0
@@ -2,4 +2,6 @@ import { UserGeneralConfig } from '@/types/user/settings';
2
2
 
3
3
  export const DEFAULT_COMMON_SETTINGS: UserGeneralConfig = {
4
4
  fontSize: 14,
5
+ highlighterTheme: 'lobe-theme',
6
+ mermaidTheme: 'lobe-theme',
5
7
  };
@@ -79,7 +79,7 @@ const AgentTTS = memo(() => {
79
79
  children: (
80
80
  <Select
81
81
  options={[
82
- { label: t('settingTheme.lang.autoMode'), value: 'auto' },
82
+ { label: t('settingCommon.lang.autoMode'), value: 'auto' },
83
83
  ...(localeOptions || []),
84
84
  ]}
85
85
  />
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+
3
+ import { ChatItemProps, ChatItem as ChatItemRaw } from '@lobehub/ui/chat';
4
+ import isEqual from 'fast-deep-equal';
5
+ import { memo } from 'react';
6
+
7
+ import { useUserStore } from '@/store/user';
8
+ import { settingsSelectors } from '@/store/user/selectors';
9
+
10
+ const ChatItem = memo<ChatItemProps>(({ markdownProps = {}, ...rest }) => {
11
+ const { componentProps, ...restMarkdown } = markdownProps;
12
+ const { general } = useUserStore(settingsSelectors.currentSettings, isEqual);
13
+ return (
14
+ <ChatItemRaw
15
+ fontSize={general.fontSize}
16
+ markdownProps={{
17
+ ...restMarkdown,
18
+ componentProps: {
19
+ ...componentProps,
20
+ highlight: {
21
+ theme: general.highlighterTheme,
22
+ ...componentProps?.highlight,
23
+ },
24
+ mermaid: {
25
+ theme: general.mermaidTheme,
26
+ ...componentProps?.mermaid,
27
+ },
28
+ },
29
+ }}
30
+ {...rest}
31
+ />
32
+ );
33
+ });
34
+
35
+ export default ChatItem;
@@ -1,19 +1,17 @@
1
1
  'use client';
2
2
 
3
- import { ChatItem } from '@lobehub/ui/chat';
4
3
  import { createStyles } from 'antd-style';
5
4
  import isEqual from 'fast-deep-equal';
6
5
  import { MouseEventHandler, ReactNode, memo, use, useCallback, useMemo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import { Flexbox } from 'react-layout-kit';
9
8
 
9
+ import ChatItem from '@/features/ChatItem';
10
10
  import { VirtuosoContext } from '@/features/Conversation/components/VirtualizedList/VirtuosoContext';
11
11
  import { useAgentStore } from '@/store/agent';
12
12
  import { agentChatConfigSelectors } from '@/store/agent/selectors';
13
13
  import { useChatStore } from '@/store/chat';
14
14
  import { chatSelectors } from '@/store/chat/selectors';
15
- import { useUserStore } from '@/store/user';
16
- import { userGeneralSettingsSelectors } from '@/store/user/selectors';
17
15
  import { ChatMessage } from '@/types/message';
18
16
 
19
17
  import ErrorMessageExtra, { useErrorContent } from '../../Error';
@@ -72,7 +70,6 @@ const Item = memo<ChatListItemProps>(
72
70
 
73
71
  const type = useAgentStore(agentChatConfigSelectors.displayMode);
74
72
  const item = useChatStore(chatSelectors.getMessageById(id), isEqual);
75
- const fontSize = useUserStore(userGeneralSettingsSelectors.fontSize);
76
73
 
77
74
  const [
78
75
  isMessageLoading,
@@ -178,7 +175,7 @@ const Item = memo<ChatListItemProps>(
178
175
  enableCustomFootnotes: item?.role === 'assistant',
179
176
  rehypePlugins: item?.role === 'user' ? undefined : rehypePlugins,
180
177
  remarkPlugins: item?.role === 'user' ? undefined : remarkPlugins,
181
- showCitations:
178
+ showFootnotes:
182
179
  item?.role === 'user'
183
180
  ? undefined
184
181
  : item?.search?.citations &&
@@ -235,7 +232,6 @@ const Item = memo<ChatListItemProps>(
235
232
  editing={editing}
236
233
  error={error}
237
234
  errorMessage={errorMessage}
238
- fontSize={fontSize}
239
235
  loading={isProcessing}
240
236
  markdownProps={markdownProps}
241
237
  message={message}
@@ -26,7 +26,7 @@ const LangButton = memo<{ placement?: PopoverProps['placement'] }>(({ placement
26
26
  () => [
27
27
  {
28
28
  key: 'auto',
29
- label: t('settingTheme.lang.autoMode'),
29
+ label: t('settingCommon.lang.autoMode'),
30
30
  onClick: () => handleLangChange('auto'),
31
31
  },
32
32
  ...localeOptions.map((item) => ({
@@ -27,19 +27,19 @@ const ThemeButton = memo<{ placement?: PopoverProps['placement'] }>(({ placement
27
27
  {
28
28
  icon: <Icon icon={themeIcons.auto} />,
29
29
  key: 'auto',
30
- label: t('settingTheme.themeMode.auto'),
30
+ label: t('settingCommon.themeMode.auto'),
31
31
  onClick: () => switchThemeMode('auto'),
32
32
  },
33
33
  {
34
34
  icon: <Icon icon={themeIcons.light} />,
35
35
  key: 'light',
36
- label: t('settingTheme.themeMode.light'),
36
+ label: t('settingCommon.themeMode.light'),
37
37
  onClick: () => switchThemeMode('light'),
38
38
  },
39
39
  {
40
40
  icon: <Icon icon={themeIcons.dark} />,
41
41
  key: 'dark',
42
- label: t('settingTheme.themeMode.dark'),
42
+ label: t('settingCommon.themeMode.dark'),
43
43
  onClick: () => switchThemeMode('dark'),
44
44
  },
45
45
  ],
@@ -10,7 +10,7 @@ import { AgentRuntime, ChatStreamPayload, LobeOpenAI, ModelProvider } from '@/li
10
10
  import { providerRuntimeMap } from '@/libs/model-runtime/runtimeMap';
11
11
  import { createTraceOptions } from '@/server/modules/AgentRuntime';
12
12
 
13
- import { AgentChatOptions } from './AgentRuntime';
13
+ import { AgentChatOptions } from './ModelRuntime';
14
14
 
15
15
  const specialProviders = [
16
16
  { id: 'openai', payload: { apiKey: 'user-openai-key', baseURL: 'user-endpoint' } },
@@ -24,7 +24,7 @@ export interface AgentChatOptions {
24
24
  trace?: TracePayload;
25
25
  }
26
26
 
27
- class AgentRuntime {
27
+ class ModelRuntime {
28
28
  private _runtime: LobeRuntimeAI;
29
29
 
30
30
  constructor(runtime: LobeRuntimeAI) {
@@ -110,8 +110,8 @@ class AgentRuntime {
110
110
  const providerAI = providerRuntimeMap[provider] ?? LobeOpenAI;
111
111
  const runtimeModel: LobeRuntimeAI = new providerAI(params);
112
112
 
113
- return new AgentRuntime(runtimeModel);
113
+ return new ModelRuntime(runtimeModel);
114
114
  }
115
115
  }
116
116
 
117
- export default AgentRuntime;
117
+ export default ModelRuntime;
@@ -1,4 +1,3 @@
1
- export { default as AgentRuntime } from './AgentRuntime';
2
1
  export { LobeAnthropicAI } from './anthropic';
3
2
  export { LobeAzureAI } from './azureai';
4
3
  export { LobeAzureOpenAI } from './azureOpenai';
@@ -11,6 +10,7 @@ export { LobeGroq } from './groq';
11
10
  export * from './helpers';
12
11
  export { LobeMinimaxAI } from './minimax';
13
12
  export { LobeMistralAI } from './mistral';
13
+ export { default as AgentRuntime } from './ModelRuntime';
14
14
  export { LobeMoonshotAI } from './moonshot';
15
15
  export { LobeOllamaAI } from './ollama';
16
16
  export { LobeOpenAI } from './openai';
@@ -25,7 +25,7 @@ export const defaultClients: ClientMetadata[] = [
25
25
  'com.lobehub.lobehub-desktop-dev://auth/callback',
26
26
  'com.lobehub.lobehub-desktop-nightly://auth/callback',
27
27
  'com.lobehub.lobehub-desktop-beta://auth/callback',
28
- 'com.lobehub.lobehub-desktop://auth/logout/callback',
28
+ 'com.lobehub.lobehub-desktop://auth/callback',
29
29
  ],
30
30
 
31
31
  // 支持授权码获取令牌和刷新令牌
@@ -172,6 +172,22 @@ export default {
172
172
  },
173
173
  title: '助手信息',
174
174
  },
175
+
176
+ settingAppearance: {
177
+ neutralColor: {
178
+ desc: '不同色彩倾向的灰阶自定义',
179
+ title: '中性色',
180
+ },
181
+ preview: {
182
+ title: '调色盘',
183
+ },
184
+ primaryColor: {
185
+ desc: '自定义主题色',
186
+ title: '主题色',
187
+ },
188
+ title: '应用外观',
189
+ },
190
+
175
191
  settingChat: {
176
192
  autoCreateTopicThreshold: {
177
193
  desc: '当前消息数超过设定该值后,将自动创建话题',
@@ -214,6 +230,35 @@ export default {
214
230
  submit: '更新聊天偏好',
215
231
  title: '聊天设置',
216
232
  },
233
+ settingChatAppearance: {
234
+ fontSize: {
235
+ desc: '聊天内容的字体大小',
236
+ marks: {
237
+ normal: '标准',
238
+ },
239
+ title: '字体大小',
240
+ },
241
+ highlighterTheme: {
242
+ title: '代码高亮主题',
243
+ },
244
+ mermaidTheme: {
245
+ title: 'Mermaid 主题',
246
+ },
247
+ title: '聊天外观',
248
+ },
249
+ settingCommon: {
250
+ lang: {
251
+ autoMode: '跟随系统',
252
+ title: '语言',
253
+ },
254
+ themeMode: {
255
+ auto: '自动',
256
+ dark: '深色',
257
+ light: '浅色',
258
+ title: '主题',
259
+ },
260
+ title: '通用设置',
261
+ },
217
262
  settingModel: {
218
263
  enableMaxTokens: {
219
264
  title: '开启单次回复限制',
@@ -339,37 +384,6 @@ export default {
339
384
  title: '语音合成声源',
340
385
  },
341
386
  },
342
- settingTheme: {
343
- avatar: {
344
- title: '头像',
345
- },
346
- fontSize: {
347
- desc: '聊天内容的字体大小',
348
- marks: {
349
- normal: '标准',
350
- },
351
- title: '字体大小',
352
- },
353
- lang: {
354
- autoMode: '跟随系统',
355
- title: '语言',
356
- },
357
- neutralColor: {
358
- desc: '不同色彩倾向的灰阶自定义',
359
- title: '中性色',
360
- },
361
- primaryColor: {
362
- desc: '自定义主题色',
363
- title: '主题色',
364
- },
365
- themeMode: {
366
- auto: '自动',
367
- dark: '深色',
368
- light: '浅色',
369
- title: '主题',
370
- },
371
- title: '主题设置',
372
- },
373
387
  storage: {
374
388
  actions: {
375
389
  export: {
@@ -5,7 +5,7 @@ export type RemoteServerError = 'CONFIG_ERROR' | 'AUTH_ERROR' | 'DISCONNECT_ERRO
5
5
  export interface ElectronState {
6
6
  appState: ElectronAppState;
7
7
  dataSyncConfig: DataSyncConfig;
8
- isAppStateInit: boolean;
8
+ isAppStateInit?: boolean;
9
9
  isConnectingServer?: boolean;
10
10
  isInitRemoteServerConfig: boolean;
11
11
  isSyncActive?: boolean;
@@ -0,0 +1,55 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { ElectronState } from '@/store/electron/initialState';
4
+
5
+ import { desktopStateSelectors } from '../desktopState';
6
+
7
+ describe('desktopStateSelectors', () => {
8
+ describe('usePath', () => {
9
+ it('should return userPath from appState', () => {
10
+ const state: ElectronState = {
11
+ isAppStateInit: false,
12
+ appState: {
13
+ userPath: {
14
+ desktop: '/test/desktop',
15
+ documents: '/test/documents',
16
+ downloads: '/test/downloads',
17
+ home: '/test/home',
18
+ music: '/test/music',
19
+ pictures: '/test/pictures',
20
+ userData: '/test/userdata',
21
+ videos: '/test/videos',
22
+ },
23
+ },
24
+ dataSyncConfig: {
25
+ storageMode: 'local',
26
+ },
27
+ isInitRemoteServerConfig: false,
28
+ };
29
+
30
+ expect(desktopStateSelectors.usePath(state)).toEqual({
31
+ desktop: '/test/desktop',
32
+ documents: '/test/documents',
33
+ downloads: '/test/downloads',
34
+ home: '/test/home',
35
+ music: '/test/music',
36
+ pictures: '/test/pictures',
37
+ userData: '/test/userdata',
38
+ videos: '/test/videos',
39
+ });
40
+ });
41
+
42
+ it('should handle undefined userPath', () => {
43
+ const state: ElectronState = {
44
+ appState: {},
45
+ isAppStateInit: false,
46
+ dataSyncConfig: {
47
+ storageMode: 'local',
48
+ },
49
+ isInitRemoteServerConfig: false,
50
+ };
51
+
52
+ expect(desktopStateSelectors.usePath(state)).toBeUndefined();
53
+ });
54
+ });
55
+ });
@@ -17,6 +17,7 @@ const showFilePanel = (s: GlobalState) => s.status.showFilePanel;
17
17
  const hidePWAInstaller = (s: GlobalState) => s.status.hidePWAInstaller;
18
18
  const isShowCredit = (s: GlobalState) => s.status.isShowCredit;
19
19
  const themeMode = (s: GlobalState) => s.status.themeMode || 'auto';
20
+ const language = (s: GlobalState) => s.status.language || 'auto';
20
21
 
21
22
  const showChatHeader = (s: GlobalState) => !s.status.zenMode;
22
23
  const inZenMode = (s: GlobalState) => s.status.zenMode;
@@ -68,6 +69,7 @@ export const systemStatusSelectors = {
68
69
  isPgliteNotEnabled,
69
70
  isPgliteNotInited,
70
71
  isShowCredit,
72
+ language,
71
73
  mobileShowPortal,
72
74
  mobileShowTopic,
73
75
  portalWidth,
@@ -15,7 +15,11 @@ describe('settingsSelectors', () => {
15
15
 
16
16
  const result = userGeneralSettingsSelectors.config(s as UserStore);
17
17
 
18
- expect(result).toEqual({ fontSize: 12 });
18
+ expect(result).toEqual({
19
+ fontSize: 12,
20
+ highlighterTheme: 'lobe-theme',
21
+ mermaidTheme: 'lobe-theme',
22
+ });
19
23
  });
20
24
  });
21
25
 
@@ -108,4 +112,28 @@ describe('settingsSelectors', () => {
108
112
  expect(result).toBe('#ffffff');
109
113
  });
110
114
  });
115
+
116
+ it('should return the highlighterTheme', () => {
117
+ const s: UserState = merge(initialState, {
118
+ settings: {
119
+ general: { highlighterTheme: 'lobe-theme' },
120
+ },
121
+ });
122
+
123
+ const result = userGeneralSettingsSelectors.highlighterTheme(s as UserStore);
124
+
125
+ expect(result).toBe('lobe-theme');
126
+ });
127
+
128
+ it('should return the mermaidTheme', () => {
129
+ const s: UserState = merge(initialState, {
130
+ settings: {
131
+ general: { mermaidTheme: 'lobe-theme' },
132
+ },
133
+ });
134
+
135
+ const result = userGeneralSettingsSelectors.mermaidTheme(s as UserStore);
136
+
137
+ expect(result).toBe('lobe-theme');
138
+ });
111
139
  });
@@ -6,10 +6,14 @@ const generalConfig = (s: UserStore) => currentSettings(s).general || {};
6
6
  const neutralColor = (s: UserStore) => generalConfig(s).neutralColor;
7
7
  const primaryColor = (s: UserStore) => generalConfig(s).primaryColor;
8
8
  const fontSize = (s: UserStore) => generalConfig(s).fontSize;
9
+ const highlighterTheme = (s: UserStore) => generalConfig(s).highlighterTheme;
10
+ const mermaidTheme = (s: UserStore) => generalConfig(s).mermaidTheme;
9
11
 
10
12
  export const userGeneralSettingsSelectors = {
11
13
  config: generalConfig,
12
14
  fontSize,
15
+ highlighterTheme,
16
+ mermaidTheme,
13
17
  neutralColor,
14
18
  primaryColor,
15
19
  };
@@ -1,7 +1,9 @@
1
- import type { NeutralColors, PrimaryColors } from '@lobehub/ui';
1
+ import type { HighlighterProps, MermaidProps, NeutralColors, PrimaryColors } from '@lobehub/ui';
2
2
 
3
3
  export interface UserGeneralConfig {
4
4
  fontSize: number;
5
+ highlighterTheme?: HighlighterProps['theme'];
6
+ mermaidTheme?: MermaidProps['theme'];
5
7
  neutralColor?: NeutralColors;
6
8
  primaryColor?: PrimaryColors;
7
9
  }
@@ -1,146 +0,0 @@
1
- 'use client';
2
-
3
- import { Form, type FormGroupItemType, ImageSelect, SliderWithInput } from '@lobehub/ui';
4
- import { Select } from '@lobehub/ui';
5
- import isEqual from 'fast-deep-equal';
6
- import { Monitor, Moon, Sun } from 'lucide-react';
7
- import { memo } from 'react';
8
- import { useTranslation } from 'react-i18next';
9
-
10
- import { useSyncSettings } from '@/app/[variants]/(main)/settings/hooks/useSyncSettings';
11
- import { FORM_STYLE } from '@/const/layoutTokens';
12
- import { imageUrl } from '@/const/url';
13
- import { Locales, localeOptions } from '@/locales/resources';
14
- import { useGlobalStore } from '@/store/global';
15
- import { systemStatusSelectors } from '@/store/global/selectors';
16
- import { useUserStore } from '@/store/user';
17
- import { settingsSelectors } from '@/store/user/selectors';
18
-
19
- import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from './ThemeSwatches';
20
-
21
- const Theme = memo(() => {
22
- const { t } = useTranslation('setting');
23
-
24
- const [form] = Form.useForm();
25
- const settings = useUserStore(settingsSelectors.currentSettings, isEqual);
26
- const themeMode = useGlobalStore(systemStatusSelectors.themeMode);
27
- const [setSettings] = useUserStore((s) => [s.setSettings]);
28
- const [setThemeMode] = useGlobalStore((s) => [s.switchThemeMode]);
29
-
30
- useSyncSettings(form);
31
- const [switchLocale] = useGlobalStore((s) => [s.switchLocale]);
32
-
33
- const handleLangChange = (value: Locales) => {
34
- switchLocale(value);
35
- };
36
-
37
- const theme: FormGroupItemType = {
38
- children: [
39
- {
40
- children: (
41
- <ImageSelect
42
- height={60}
43
- onChange={setThemeMode}
44
- options={[
45
- {
46
- icon: Sun,
47
- img: imageUrl('theme_light.webp'),
48
- label: t('settingTheme.themeMode.light'),
49
- value: 'light',
50
- },
51
- {
52
- icon: Moon,
53
- img: imageUrl('theme_dark.webp'),
54
- label: t('settingTheme.themeMode.dark'),
55
- value: 'dark',
56
- },
57
- {
58
- icon: Monitor,
59
- img: imageUrl('theme_auto.webp'),
60
- label: t('settingTheme.themeMode.auto'),
61
- value: 'auto',
62
- },
63
- ]}
64
- unoptimized={false}
65
- value={themeMode}
66
- width={100}
67
- />
68
- ),
69
- label: t('settingTheme.themeMode.title'),
70
- minWidth: undefined,
71
- },
72
- {
73
- children: (
74
- <Select
75
- onChange={handleLangChange}
76
- options={[{ label: t('settingTheme.lang.autoMode'), value: 'auto' }, ...localeOptions]}
77
- />
78
- ),
79
- label: t('settingTheme.lang.title'),
80
- name: ['general', 'language'],
81
- },
82
- {
83
- children: (
84
- <SliderWithInput
85
- marks={{
86
- 12: {
87
- label: 'A',
88
- style: {
89
- fontSize: 12,
90
- marginTop: 4,
91
- },
92
- },
93
- 14: {
94
- label: t('settingTheme.fontSize.marks.normal'),
95
- style: {
96
- fontSize: 14,
97
- marginTop: 4,
98
- },
99
- },
100
- 18: {
101
- label: 'A',
102
- style: {
103
- fontSize: 18,
104
- marginTop: 4,
105
- },
106
- },
107
- }}
108
- max={18}
109
- min={12}
110
- step={1}
111
- />
112
- ),
113
- desc: t('settingTheme.fontSize.desc'),
114
- label: t('settingTheme.fontSize.title'),
115
- name: ['general', 'fontSize'],
116
- },
117
- {
118
- children: <ThemeSwatchesPrimary />,
119
- desc: t('settingTheme.primaryColor.desc'),
120
- label: t('settingTheme.primaryColor.title'),
121
- minWidth: undefined,
122
- },
123
- {
124
- children: <ThemeSwatchesNeutral />,
125
- desc: t('settingTheme.neutralColor.desc'),
126
- label: t('settingTheme.neutralColor.title'),
127
- minWidth: undefined,
128
- },
129
- ],
130
- title: t('settingTheme.title'),
131
- };
132
-
133
- return (
134
- <Form
135
- form={form}
136
- initialValues={settings}
137
- items={[theme]}
138
- itemsType={'group'}
139
- onValuesChange={setSettings}
140
- variant={'borderless'}
141
- {...FORM_STYLE}
142
- />
143
- );
144
- });
145
-
146
- export default Theme;