@lobehub/lobehub 2.0.0-next.323 → 2.0.0-next.325

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 (71) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/CLAUDE.md +4 -0
  3. package/apps/desktop/src/main/core/browser/Browser.ts +40 -1
  4. package/apps/desktop/src/main/core/infrastructure/I18nManager.ts +0 -11
  5. package/changelog/v1.json +14 -0
  6. package/package.json +2 -2
  7. package/packages/database/src/models/__tests__/session.test.ts +0 -29
  8. package/src/app/[variants]/(desktop)/desktop-onboarding/components/LobeMessage.tsx +5 -0
  9. package/src/app/[variants]/(desktop)/desktop-onboarding/features/WelcomeStep.tsx +3 -1
  10. package/src/app/[variants]/(main)/agent/features/Conversation/AgentWelcome/OpeningQuestions.tsx +0 -2
  11. package/src/app/[variants]/(main)/community/(detail)/agent/features/Sidebar/TocList/index.tsx +0 -36
  12. package/src/app/[variants]/(main)/community/(list)/_layout/Header.tsx +0 -2
  13. package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/GroupMember.tsx +0 -4
  14. package/src/app/[variants]/(main)/group/features/Conversation/ConversationArea.tsx +0 -7
  15. package/src/app/[variants]/(main)/group/features/Conversation/MainChatInput/GroupChat.tsx +0 -2
  16. package/src/app/[variants]/(main)/home/_layout/Body/index.tsx +0 -2
  17. package/src/app/[variants]/(main)/home/features/WelcomeText/index.tsx +3 -1
  18. package/src/app/[variants]/(main)/page/_layout/Body/List/Item/useDropdownMenu.tsx +0 -6
  19. package/src/app/[variants]/(main)/page/_layout/Body/useDropdownMenu.tsx +0 -15
  20. package/src/app/[variants]/(main)/resource/features/DndContextWrapper.tsx +0 -5
  21. package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/index.tsx +0 -1
  22. package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelItem.tsx +0 -10
  23. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/Checker.tsx +1 -1
  24. package/src/app/[variants]/(mobile)/(home)/features/SessionListContent/List/Item/Actions.tsx +0 -1
  25. package/src/app/[variants]/layout.tsx +0 -2
  26. package/src/app/[variants]/onboarding/components/LobeMessage.tsx +5 -0
  27. package/src/app/[variants]/onboarding/features/TelemetryStep.tsx +3 -1
  28. package/src/envs/__tests__/app.test.ts +0 -6
  29. package/src/features/ChatInput/ActionBar/Knowledge/useControls.tsx +0 -22
  30. package/src/features/ChatInput/store/action.ts +0 -2
  31. package/src/features/Conversation/Messages/Task/TaskDetailPanel/index.tsx +1 -13
  32. package/src/features/DataImporter/ImportDetail.tsx +0 -20
  33. package/src/features/DevPanel/features/Table/TableCell.tsx +1 -36
  34. package/src/features/DevPanel/index.tsx +0 -9
  35. package/src/features/ModelSwitchPanel/__mocks__/mockEnabledChatModels.ts +159 -0
  36. package/src/features/ModelSwitchPanel/components/List/{VirtualItemRenderer.tsx → ListItemRenderer.tsx} +15 -25
  37. package/src/features/ModelSwitchPanel/components/List/MultipleProvidersModelItem.tsx +95 -69
  38. package/src/features/ModelSwitchPanel/components/List/index.tsx +39 -40
  39. package/src/features/ModelSwitchPanel/components/PanelContent.tsx +0 -8
  40. package/src/features/ModelSwitchPanel/hooks/{useBuildVirtualItems.ts → useBuildListItems.ts} +7 -17
  41. package/src/features/ModelSwitchPanel/index.tsx +24 -23
  42. package/src/features/ModelSwitchPanel/styles.ts +3 -0
  43. package/src/features/ModelSwitchPanel/types.ts +3 -8
  44. package/src/features/ModelSwitchPanel/utils.ts +2 -2
  45. package/src/features/NavPanel/SideBarDrawer.tsx +12 -2
  46. package/src/features/Portal/GroupThread/Body/index.tsx +0 -6
  47. package/src/features/ResourceManager/components/Header/AddButton.tsx +0 -16
  48. package/src/features/ShareModal/ShareImage/index.tsx +0 -8
  49. package/src/hooks/useProviderName.ts +0 -1
  50. package/src/layout/GlobalProvider/Locale.tsx +0 -12
  51. package/src/layout/GlobalProvider/index.tsx +0 -1
  52. package/src/libs/better-auth/sso/helpers.ts +0 -1
  53. package/src/libs/next/config/define-config.ts +5 -0
  54. package/src/locales/create.ts +0 -17
  55. package/src/services/aiChat.ts +0 -4
  56. package/src/services/debug.ts +1 -34
  57. package/src/services/models.ts +0 -15
  58. package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +0 -9
  59. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +0 -3
  60. package/src/store/chat/slices/aiChat/actions/index.ts +1 -3
  61. package/src/store/file/slices/chat/action.test.ts +0 -89
  62. package/src/store/file/slices/chunk/selectors.ts +0 -1
  63. package/src/store/file/slices/fileManager/selectors.ts +0 -1
  64. package/src/store/file/slices/tts/selectors.ts +0 -2
  65. package/src/store/tool/slices/customPlugin/index.ts +0 -1
  66. package/src/store/tool/slices/mcpStore/index.ts +0 -1
  67. package/src/store/tool/slices/oldStore/index.ts +0 -1
  68. package/src/store/tool/slices/plugin/index.ts +0 -1
  69. package/src/styles/global.ts +6 -0
  70. package/src/utils/router.tsx +1 -7
  71. package/src/utils/server/parseModels.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,64 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.325](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.324...v2.0.0-next.325)
6
+
7
+ <sup>Released on **2026-01-20**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **ModelSwitchPanel**: Migrate from Popover to DropdownMenu with virtual scrolling.
12
+
13
+ #### 🐛 Bug Fixes
14
+
15
+ - **sidebar-drawer**: Fix drawer positioning and title style.
16
+
17
+ <br/>
18
+
19
+ <details>
20
+ <summary><kbd>Improvements and Fixes</kbd></summary>
21
+
22
+ #### Code refactoring
23
+
24
+ - **ModelSwitchPanel**: Migrate from Popover to DropdownMenu with virtual scrolling, closes [#11663](https://github.com/lobehub/lobe-chat/issues/11663) ([c9d9dff](https://github.com/lobehub/lobe-chat/commit/c9d9dff))
25
+
26
+ #### What's fixed
27
+
28
+ - **sidebar-drawer**: Fix drawer positioning and title style, closes [#11655](https://github.com/lobehub/lobe-chat/issues/11655) ([cf5320e](https://github.com/lobehub/lobe-chat/commit/cf5320e))
29
+
30
+ </details>
31
+
32
+ <div align="right">
33
+
34
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
35
+
36
+ </div>
37
+
38
+ ## [Version 2.0.0-next.324](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.323...v2.0.0-next.324)
39
+
40
+ <sup>Released on **2026-01-20**</sup>
41
+
42
+ #### 🐛 Bug Fixes
43
+
44
+ - **misc**: TypewriterEffect not refreshing on language change.
45
+
46
+ <br/>
47
+
48
+ <details>
49
+ <summary><kbd>Improvements and Fixes</kbd></summary>
50
+
51
+ #### What's fixed
52
+
53
+ - **misc**: TypewriterEffect not refreshing on language change, closes [#11657](https://github.com/lobehub/lobe-chat/issues/11657) ([ba30f46](https://github.com/lobehub/lobe-chat/commit/ba30f46))
54
+
55
+ </details>
56
+
57
+ <div align="right">
58
+
59
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
60
+
61
+ </div>
62
+
5
63
  ## [Version 2.0.0-next.323](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.322...v2.0.0-next.323)
6
64
 
7
65
  <sup>Released on **2026-01-20**</sup>
package/CLAUDE.md CHANGED
@@ -32,6 +32,10 @@ This repository adopts a monorepo structure.
32
32
 
33
33
  see @.cursor/rules/typescript.mdc
34
34
 
35
+ ### Code Comments
36
+
37
+ - **Avoid meaningless comments**: Do not write comments that merely restate what the code does. Comments should explain _why_ something is done, not _what_ is being done. The code itself should be self-explanatory.
38
+
35
39
  ### Testing
36
40
 
37
41
  - **Required Rule**: read `.cursor/rules/testing-guide/testing-guide.mdc` before writing tests
@@ -3,6 +3,7 @@ import { MainBroadcastEventKey, MainBroadcastParams } from '@lobechat/electron-c
3
3
  import {
4
4
  BrowserWindow,
5
5
  BrowserWindowConstructorOptions,
6
+ Menu,
6
7
  session as electronSession,
7
8
  ipcMain,
8
9
  screen,
@@ -11,7 +12,7 @@ import console from 'node:console';
11
12
  import { join } from 'node:path';
12
13
 
13
14
  import { preloadDir, resourcesDir } from '@/const/dir';
14
- import { isMac } from '@/const/env';
15
+ import { isDev, isMac } from '@/const/env';
15
16
  import { ELECTRON_BE_PROTOCOL_SCHEME } from '@/const/protocol';
16
17
  import RemoteServerConfigCtr from '@/controllers/RemoteServerConfigCtr';
17
18
  import { backendProxyProtocolManager } from '@/core/infrastructure/BackendProxyProtocolManager';
@@ -191,6 +192,7 @@ export default class Browser {
191
192
  this.setupCloseListener(browserWindow);
192
193
  this.setupFocusListener(browserWindow);
193
194
  this.setupWillPreventUnloadListener(browserWindow);
195
+ this.setupDevContextMenu(browserWindow);
194
196
  }
195
197
 
196
198
  private setupWillPreventUnloadListener(browserWindow: BrowserWindow): void {
@@ -236,6 +238,43 @@ export default class Browser {
236
238
  });
237
239
  }
238
240
 
241
+ /**
242
+ * Setup context menu with "Inspect Element" option in development mode
243
+ */
244
+ private setupDevContextMenu(browserWindow: BrowserWindow): void {
245
+ if (!isDev) return;
246
+
247
+ logger.debug(`[${this.identifier}] Setting up dev context menu.`);
248
+
249
+ browserWindow.webContents.on('context-menu', (_event, params) => {
250
+ const { x, y } = params;
251
+
252
+ const menu = Menu.buildFromTemplate([
253
+ {
254
+ click: () => {
255
+ browserWindow.webContents.inspectElement(x, y);
256
+ },
257
+ label: 'Inspect Element',
258
+ },
259
+ { type: 'separator' },
260
+ {
261
+ click: () => {
262
+ browserWindow.webContents.openDevTools();
263
+ },
264
+ label: 'Open DevTools',
265
+ },
266
+ {
267
+ click: () => {
268
+ browserWindow.webContents.reload();
269
+ },
270
+ label: 'Reload',
271
+ },
272
+ ]);
273
+
274
+ menu.popup({ window: browserWindow });
275
+ });
276
+ }
277
+
239
278
  // ==================== Window Actions ====================
240
279
 
241
280
  show(): void {
@@ -149,17 +149,6 @@ export class I18nManager {
149
149
  */
150
150
  private notifyRendererProcess(lng: string) {
151
151
  logger.debug(`Notifying renderer process of language change: ${lng}`);
152
-
153
- // Send language change event to all windows
154
- // const windows = this.app.browserManager.windows;
155
- //
156
- // if (windows && windows.length > 0) {
157
- // windows.forEach((window) => {
158
- // if (window?.webContents) {
159
- // window.webContents.send('language-changed', lng);
160
- // }
161
- // });
162
- // }
163
152
  }
164
153
 
165
154
  private async loadLocale(language: string) {
package/changelog/v1.json CHANGED
@@ -1,4 +1,18 @@
1
1
  [
2
+ {
3
+ "children": {},
4
+ "date": "2026-01-20",
5
+ "version": "2.0.0-next.325"
6
+ },
7
+ {
8
+ "children": {
9
+ "fixes": [
10
+ "TypewriterEffect not refreshing on language change."
11
+ ]
12
+ },
13
+ "date": "2026-01-20",
14
+ "version": "2.0.0-next.324"
15
+ },
2
16
  {
3
17
  "children": {
4
18
  "improvements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.323",
3
+ "version": "2.0.0-next.325",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent 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",
@@ -207,7 +207,7 @@
207
207
  "@lobehub/icons": "^4.0.2",
208
208
  "@lobehub/market-sdk": "0.29.1",
209
209
  "@lobehub/tts": "^4.0.2",
210
- "@lobehub/ui": "^4.22.0",
210
+ "@lobehub/ui": "^4.24.0",
211
211
  "@modelcontextprotocol/sdk": "^1.25.1",
212
212
  "@neondatabase/serverless": "^1.0.2",
213
213
  "@next/third-parties": "^16.1.1",
@@ -235,35 +235,6 @@ describe('SessionModel', () => {
235
235
  });
236
236
  });
237
237
 
238
- // describe('getAgentConfigById', () => {
239
- // it('should return agent config by id', async () => {
240
- // await serverDB.transaction(async (trx) => {
241
- // await trx.insert(agents).values([
242
- // { id: '1', userId, model: 'gpt-3.5-turbo' },
243
- // { id: '2', userId, model: 'gpt-3.5' },
244
- // ]);
245
- //
246
- // // @ts-ignore
247
- // await trx.insert(plugins).values([
248
- // { id: 1, userId, identifier: 'abc', title: 'A1', locale: 'en-US', manifest: {} },
249
- // { id: 2, userId, identifier: 'b2', title: 'A2', locale: 'en-US', manifest: {} },
250
- // ]);
251
- //
252
- // await trx.insert(agentsPlugins).values([
253
- // { agentId: '1', pluginId: 1 },
254
- // { agentId: '2', pluginId: 2 },
255
- // { agentId: '1', pluginId: 2 },
256
- // ]);
257
- // });
258
- //
259
- // const result = await sessionModel.getAgentConfigById('1');
260
- //
261
- // expect(result?.id).toBe('1');
262
- // expect(result?.plugins).toBe(['abc', 'b2']);
263
- // expect(result?.model).toEqual('gpt-3.5-turbo');
264
- // expect(result?.chatConfig).toBeDefined();
265
- // });
266
- // });
267
238
  describe('count', () => {
268
239
  it('should return the count of sessions for the user', async () => {
269
240
  // 创建测试数据
@@ -2,6 +2,7 @@ import { Flexbox, type FlexboxProps, Text } from '@lobehub/ui';
2
2
  import { TypewriterEffect, type TypewriterEffectProps } from '@lobehub/ui/awesome';
3
3
  import { LoadingDots } from '@lobehub/ui/chat';
4
4
  import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
5
6
 
6
7
  import { ProductLogo } from '@/components/Branding';
7
8
 
@@ -11,6 +12,9 @@ interface LobeMessageProps extends Omit<FlexboxProps, 'children'> {
11
12
  }
12
13
 
13
14
  const LobeMessage = memo<LobeMessageProps>(({ sentences, fontSize = 24, ...rest }) => {
15
+ const { i18n } = useTranslation();
16
+ const locale = i18n.language;
17
+
14
18
  return (
15
19
  <Flexbox gap={8} {...rest}>
16
20
  <ProductLogo size={fontSize * 2} />
@@ -21,6 +25,7 @@ const LobeMessage = memo<LobeMessageProps>(({ sentences, fontSize = 24, ...rest
21
25
  deletePauseDuration={1000}
22
26
  deletingSpeed={32}
23
27
  hideCursorWhileTyping={'afterTyping'}
28
+ key={locale}
24
29
  pauseDuration={16_000}
25
30
  sentences={sentences}
26
31
  typingSpeed={64}
@@ -17,7 +17,8 @@ interface WelcomeStepProps {
17
17
  }
18
18
 
19
19
  const WelcomeStep = memo<WelcomeStepProps>(({ onNext }) => {
20
- const { t } = useTranslation('onboarding');
20
+ const { t, i18n } = useTranslation('onboarding');
21
+ const locale = i18n.language;
21
22
  const updateGeneralConfig = useUserStore((s) => s.updateGeneralConfig);
22
23
 
23
24
  const handleNext = () => {
@@ -53,6 +54,7 @@ const WelcomeStep = memo<WelcomeStepProps>(({ onNext }) => {
53
54
  deletePauseDuration={1000}
54
55
  deletingSpeed={32}
55
56
  hideCursorWhileTyping={'afterTyping'}
57
+ key={locale}
56
58
  pauseDuration={16_000}
57
59
  sentences={[
58
60
  t('telemetry.title', { name: 'Lobe AI' }),
@@ -7,8 +7,6 @@ import { useTranslation } from 'react-i18next';
7
7
 
8
8
  import { useConversationStore } from '@/features/Conversation';
9
9
 
10
- // import { useSend } from '../../features/ChatInput/useSend';
11
-
12
10
  const styles = createStaticStyles(({ css, cssVar }) => ({
13
11
  card: css`
14
12
  padding-block: 8px;
@@ -16,42 +16,6 @@ const TocList = memo(() => {
16
16
  const { t } = useTranslation('discover');
17
17
  const { toc = [] } = useToc();
18
18
  const { activeTab = AssistantNavKey.Overview } = useQuery() as { activeTab: AssistantNavKey };
19
- // const { deploymentOptions = [], tools = [], prompts = [] } = useDetailContext();
20
- //
21
- // const schemaToc: AnchorProps['items'] = useMemo(() => {
22
- // return [
23
- // {
24
- // href: `#tools`,
25
- // key: `tools`,
26
- // level: 2,
27
- // title: t('mcp.details.schema.tools.title'),
28
- // },
29
- // ...tools.map((item) => ({
30
- // href: `#tools-${item.name}`,
31
- // key: `tools-${item.name}`,
32
- // level: 3,
33
- // title: item.name,
34
- // })),
35
- // {
36
- // href: `#prompts`,
37
- // key: `prompts`,
38
- // level: 2,
39
- // title: t('mcp.details.schema.prompts.title'),
40
- // },
41
- // ...prompts.map((item) => ({
42
- // href: `#prompts-${item.name}`,
43
- // key: `prompts-${item.name}`,
44
- // level: 3,
45
- // title: item.name,
46
- // })),
47
- // {
48
- // href: `#resources`,
49
- // key: `resources`,
50
- // level: 2,
51
- // title: t('mcp.details.schema.resources.title'),
52
- // },
53
- // ].filter(Boolean) as AnchorProps['items'];
54
- // }, [tools, prompts, t]);
55
19
 
56
20
  const items: AnchorProps['items'] | undefined = useMemo(() => {
57
21
  switch (activeTab) {
@@ -13,7 +13,6 @@ import { styles } from './Header/style';
13
13
 
14
14
  const Header = memo(() => {
15
15
  const location = useLocation();
16
- // const { activeKey } = useNav();
17
16
  const isHome = location.pathname === '/';
18
17
 
19
18
  const cssVariables: Record<string, string> = {
@@ -27,7 +26,6 @@ const Header = memo(() => {
27
26
  right={
28
27
  !isHome && (
29
28
  <>
30
- {/*{activeKey === DiscoverTab.Assistants && <MarketSourceSwitch />}*/}
31
29
  <SortButton />
32
30
  <UserAvatar />
33
31
  </>
@@ -41,12 +41,8 @@ const GroupMember = memo<GroupMemberProps>(({ addModalOpen, onAddModalOpenChange
41
41
  const toggleThread = useAgentGroupStore((s) => s.toggleThread);
42
42
  const pushPortalView = useChatStore((s) => s.pushPortalView);
43
43
 
44
- // Get members from store (excluding supervisor)
45
44
  const groupMembers = useAgentGroupStore(agentGroupSelectors.getGroupMembers(groupId || ''));
46
45
 
47
- // const [agentSettingsOpen, setAgentSettingsOpen] = useState(false);
48
- // const [selectedAgentId, setSelectedAgentId] = useState<string | undefined>();
49
-
50
46
  const handleAddMembers = async (selectedAgents: string[]) => {
51
47
  if (!groupId) {
52
48
  console.error('No active group to add members to');
@@ -18,8 +18,6 @@ import ThreadHydration from './ThreadHydration';
18
18
  import { useActionsBarConfig } from './useActionsBarConfig';
19
19
  import { useGroupContext } from './useGroupContext';
20
20
 
21
- // import { useGroupHooks } from './useGroupHooks';
22
-
23
21
  interface ConversationAreaProps {
24
22
  mobile?: boolean;
25
23
  }
@@ -45,18 +43,13 @@ const Conversation = memo<ConversationAreaProps>(({ mobile = false }) => {
45
43
  // Get operation state from ChatStore for reactive updates
46
44
  const operationState = useOperationState(context);
47
45
 
48
- // Get actionsBar config with branching support from ChatStore
49
46
  const actionsBarConfig = useActionsBarConfig();
50
47
 
51
- // Get group-specific hooks for send logic
52
- // const groupHooks = useGroupHooks(context);
53
-
54
48
  return (
55
49
  <ConversationProvider
56
50
  actionsBar={actionsBarConfig}
57
51
  context={context}
58
52
  hasInitMessages={!!messages}
59
- // hooks={groupHooks}
60
53
  messages={messages}
61
54
  onMessagesChange={(messages, ctx) => {
62
55
  replaceMessages(messages, { context: ctx });
@@ -35,7 +35,6 @@ const rightActions: ActionKeys[] = [];
35
35
  */
36
36
  const Desktop = memo((props: { targetMemberId?: string }) => {
37
37
  const { t } = useTranslation('chat');
38
- // const { send, generating, disabled, stop } = useSendGroupMessage();
39
38
 
40
39
  const isDMPortal = !!props.targetMemberId;
41
40
  const currentGroupMembers = useAgentGroupStore(agentGroupSelectors.currentGroupAgents, isEqual);
@@ -93,7 +92,6 @@ const Desktop = memo((props: { targetMemberId?: string }) => {
93
92
  useChatStore.setState({ inputMessage: content });
94
93
  }}
95
94
  rightActions={isDMPortal ? [] : rightActions}
96
- // sendButtonProps={{ disabled, generating, onStop: stop }}
97
95
  sendMenu={{
98
96
  items: sendMenuItems,
99
97
  }}
@@ -12,11 +12,9 @@ export enum GroupKey {
12
12
  }
13
13
 
14
14
  const Body = memo(() => {
15
- // const { enableKnowledgeBase } = useServerConfigStore(featureFlagsSelectors);
16
15
  return (
17
16
  <Flexbox paddingInline={4}>
18
17
  <Accordion defaultExpandedKeys={[GroupKey.Project, GroupKey.Agent]} gap={8}>
19
- {/*{enableKnowledgeBase && <Repo itemKey={GroupKey.Project} />}*/}
20
18
  <Agent itemKey={GroupKey.Agent} />
21
19
  <BottomMenu />
22
20
  </Accordion>
@@ -7,7 +7,8 @@ import { memo, useMemo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
 
9
9
  const WelcomeText = memo(() => {
10
- const { t } = useTranslation('welcome');
10
+ const { t, i18n } = useTranslation('welcome');
11
+ const locale = i18n.language;
11
12
 
12
13
  const sentences = useMemo(() => {
13
14
  const messages = t('welcomeMessages', { returnObjects: true }) as Record<string, string>;
@@ -28,6 +29,7 @@ const WelcomeText = memo(() => {
28
29
  deletePauseDuration={1000}
29
30
  deletingSpeed={32}
30
31
  hideCursorWhileTyping={'afterTyping'}
32
+ key={locale}
31
33
  pauseDuration={16_000}
32
34
  sentences={sentences}
33
35
  typingSpeed={64}
@@ -56,12 +56,6 @@ export const useDropdownMenu = ({
56
56
  label: t('rename'),
57
57
  onClick: () => toggleEditing(true),
58
58
  },
59
- // {
60
- // icon: <Icon icon={Copy} />,
61
- // key: 'copy',
62
- // label: t('pageList.copyContent', { ns: 'file' }),
63
- // onClick: handleCopy,
64
- // },
65
59
  {
66
60
  icon: <Icon icon={CopyPlus} />,
67
61
  key: 'duplicate',
@@ -32,21 +32,6 @@ export const useDropdownMenu = (): MenuProps['items'] => {
32
32
  }));
33
33
 
34
34
  return [
35
- // {
36
- // icon: <Icon icon={Check} style={{ opacity: !showOnlyPagesNotInLibrary ? 1 : 0 }} />,
37
- // key: 'all',
38
- // label: t('pageList.filter.all'),
39
- // onClick: () => setShowOnlyPagesNotInLibrary(false),
40
- // },
41
- // {
42
- // icon: <Icon icon={Check} style={{ opacity: showOnlyPagesNotInLibrary ? 1 : 0 }} />,
43
- // key: 'onlyInPages',
44
- // label: t('pageList.filter.onlyInPages'),
45
- // onClick: () => setShowOnlyPagesNotInLibrary(true),
46
- // },
47
- // {
48
- // type: 'divider' as const,
49
- // },
50
35
  {
51
36
  children: pageSizeItems,
52
37
  icon: <Icon icon={Hash} />,
@@ -141,11 +141,6 @@ export const DndContextWrapper = memo<PropsWithChildren>(({ children }) => {
141
141
  return;
142
142
  }
143
143
 
144
- // Save current drag data before clearing state
145
- // const draggedItemId = currentDrag.id;
146
- // const draggedItemData = currentDrag.data;
147
-
148
- // Clear drag state immediately for better UX
149
144
  setCurrentDrag(null);
150
145
 
151
146
  // Show loading toast
@@ -51,7 +51,6 @@ const ModelConfigModal = memo<ModelConfigModalProps>(({ open, setOpen }) => {
51
51
  setLoading(false);
52
52
  closeModal();
53
53
  } catch {
54
- /* */
55
54
  setLoading(false);
56
55
  }
57
56
  }}
@@ -240,16 +240,6 @@ const ModelItem = memo<ModelItemProps>(
240
240
  {...abilities}
241
241
  contextWindowTokens={contextWindowTokens}
242
242
  />
243
- {/*{removed && (*/}
244
- {/* <Tooltip*/}
245
- {/* overlayStyle={{ maxWidth: 300 }}*/}
246
- {/* placement={'top'}*/}
247
- {/* style={{ pointerEvents: 'none' }}*/}
248
- {/* title={t('ModelSelect.removed')}*/}
249
- {/* >*/}
250
- {/* <ActionIcon icon={Recycle} style={{ color: theme.colorWarning }} />*/}
251
- {/* </Tooltip>*/}
252
- {/*)}*/}
253
243
  </Flexbox>
254
244
  </Flexbox>
255
245
  <div>
@@ -3,7 +3,7 @@
3
3
  import { CheckCircleFilled } from '@ant-design/icons';
4
4
  import { type ChatMessageError, TraceNameMap } from '@lobechat/types';
5
5
  import { ModelIcon } from '@lobehub/icons';
6
- import { Alert, Button, Flexbox, Highlighter, Icon, Select } from '@lobehub/ui';
6
+ import { Alert, Button, Flexbox, Highlighter, Icon, LobeSelect as Select } from '@lobehub/ui';
7
7
  import { cssVar } from 'antd-style';
8
8
  import { Loader2Icon } from 'lucide-react';
9
9
  import { type ReactNode, memo, useEffect, useState } from 'react';
@@ -66,7 +66,6 @@ const Actions = memo<ActionProps>(({ group, id, openCreateGroupModal, parentType
66
66
  const { modal, message } = App.useApp();
67
67
 
68
68
  const isDefault = group === SessionDefaultGroup.Default;
69
- // const hasDivider = !isDefault || Object.keys(sessionByGroup).length > 0;
70
69
 
71
70
  const items = useMemo(
72
71
  () =>
@@ -52,8 +52,6 @@ const RootLayout = async ({ children, params }: RootLayoutProps) => {
52
52
  <head>
53
53
  {/* eslint-disable-next-line @typescript-eslint/no-use-before-define */}
54
54
  <script dangerouslySetInnerHTML={{ __html: `(${outdateBrowserScript.toString()})();` }} />
55
-
56
- {/* <script dangerouslySetInnerHTML={{ __html: 'setTimeout(() => {debugger}, 16)' }} /> */}
57
55
  {process.env.DEBUG_REACT_SCAN === '1' && (
58
56
  <Script
59
57
  crossOrigin={'anonymous'}
@@ -2,6 +2,7 @@ import { Flexbox, type FlexboxProps, Text } from '@lobehub/ui';
2
2
  import { TypewriterEffect, type TypewriterEffectProps } from '@lobehub/ui/awesome';
3
3
  import { LoadingDots } from '@lobehub/ui/chat';
4
4
  import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
5
6
 
6
7
  import { ProductLogo } from '@/components/Branding';
7
8
 
@@ -11,6 +12,9 @@ interface LobeMessageProps extends Omit<FlexboxProps, 'children'> {
11
12
  }
12
13
 
13
14
  const LobeMessage = memo<LobeMessageProps>(({ sentences, fontSize = 24, ...rest }) => {
15
+ const { i18n } = useTranslation();
16
+ const locale = i18n.language;
17
+
14
18
  return (
15
19
  <Flexbox gap={8} {...rest}>
16
20
  <ProductLogo size={fontSize * 2} />
@@ -21,6 +25,7 @@ const LobeMessage = memo<LobeMessageProps>(({ sentences, fontSize = 24, ...rest
21
25
  deletePauseDuration={1000}
22
26
  deletingSpeed={32}
23
27
  hideCursorWhileTyping={'afterTyping'}
28
+ key={locale}
24
29
  pauseDuration={16_000}
25
30
  sentences={sentences}
26
31
  typingSpeed={64}
@@ -19,7 +19,8 @@ interface TelemetryStepProps {
19
19
  }
20
20
 
21
21
  const TelemetryStep = memo<TelemetryStepProps>(({ onNext }) => {
22
- const { t } = useTranslation('onboarding');
22
+ const { t, i18n } = useTranslation('onboarding');
23
+ const locale = i18n.language;
23
24
  const [check, setCheck] = useState(true);
24
25
  const [isNavigating, setIsNavigating] = useState(false);
25
26
  const isNavigatingRef = useRef(false);
@@ -63,6 +64,7 @@ const TelemetryStep = memo<TelemetryStepProps>(({ onNext }) => {
63
64
  deletePauseDuration={1000}
64
65
  deletingSpeed={32}
65
66
  hideCursorWhileTyping={'afterTyping'}
67
+ key={locale}
66
68
  pauseDuration={16_000}
67
69
  sentences={[
68
70
  t('telemetry.title', { name: 'Lobe AI' }),
@@ -7,12 +7,6 @@ describe('getServerConfig', () => {
7
7
  vi.resetModules();
8
8
  });
9
9
 
10
- // it('correctly handles values for OPENAI_FUNCTION_REGIONS', () => {
11
- // process.env.OPENAI_FUNCTION_REGIONS = 'iad1,sfo1';
12
- // const config = getAppConfig();
13
- // expect(config.OPENAI_FUNCTION_REGIONS).toStrictEqual(['iad1', 'sfo1']);
14
- // });
15
-
16
10
  describe('index url', () => {
17
11
  it('should return default URLs when no environment variables are set', async () => {
18
12
  const { getAppConfig } = await import('../app');
@@ -33,28 +33,6 @@ export const useControls = ({
33
33
  ]);
34
34
 
35
35
  const items: ItemType[] = [
36
- // {
37
- // children: [
38
- // {
39
- // icon: <RepoIcon />,
40
- // key: 'allFiles',
41
- // label: <KnowledgeBaseItem id={'all'} label={t('knowledgeBase.allFiles')} />,
42
- // },
43
- // {
44
- // icon: <RepoIcon />,
45
- // key: 'allRepos',
46
- // label: <KnowledgeBaseItem id={'all'} label={t('knowledgeBase.allLibraries')} />,
47
- // },
48
- // ],
49
- // key: 'all',
50
- // label: (
51
- // <Flexbox horizontal justify={'space-between'}>
52
- // {t('knowledgeBase.all')}
53
- // {/*<Link href={'/files'}>{t('knowledgeBase.more')}</Link>*/}
54
- // </Flexbox>
55
- // ),
56
- // type: 'group',
57
- // },
58
36
  {
59
37
  children: [
60
38
  // first the files
@@ -15,8 +15,6 @@ export interface Action {
15
15
 
16
16
  export type Store = Action & State;
17
17
 
18
- // const t = setNamespace('ChatInput');
19
-
20
18
  type CreateStore = (
21
19
  initState?: Partial<PublicState>,
22
20
  ) => StateCreator<Store, [['zustand/devtools', never]]>;