@lobehub/chat 1.36.34 → 1.36.35

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 (38) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.ja-JP.md +1 -1
  3. package/README.md +8 -8
  4. package/README.zh-CN.md +1 -1
  5. package/changelog/v1.json +9 -0
  6. package/locales/ar/common.json +27 -7
  7. package/locales/bg-BG/common.json +27 -7
  8. package/locales/de-DE/common.json +27 -7
  9. package/locales/en-US/common.json +27 -7
  10. package/locales/es-ES/common.json +27 -7
  11. package/locales/fa-IR/common.json +27 -7
  12. package/locales/fr-FR/common.json +27 -7
  13. package/locales/it-IT/common.json +27 -7
  14. package/locales/ja-JP/common.json +27 -7
  15. package/locales/ko-KR/common.json +27 -7
  16. package/locales/nl-NL/common.json +27 -7
  17. package/locales/pl-PL/common.json +27 -7
  18. package/locales/pt-BR/common.json +27 -7
  19. package/locales/ru-RU/common.json +27 -7
  20. package/locales/tr-TR/common.json +27 -7
  21. package/locales/vi-VN/common.json +27 -7
  22. package/locales/zh-CN/common.json +28 -8
  23. package/locales/zh-TW/common.json +27 -7
  24. package/package.json +1 -1
  25. package/src/app/loading/Client/Content.tsx +38 -0
  26. package/src/app/loading/Client/Redirect.tsx +47 -0
  27. package/src/app/loading/Client/index.tsx +22 -0
  28. package/src/app/loading/{Content.tsx → Server/Content.tsx} +6 -2
  29. package/src/app/loading/{Redirect.tsx → Server/Redirect.tsx} +3 -12
  30. package/src/app/loading/Server/index.tsx +22 -0
  31. package/src/app/loading/index.tsx +4 -16
  32. package/src/app/loading/stage.ts +22 -0
  33. package/src/components/FullscreenLoading/index.tsx +9 -8
  34. package/src/components/InitProgress/index.tsx +42 -0
  35. package/src/features/MobileSwitchLoading/index.tsx +20 -7
  36. package/src/layout/AuthProvider/NextAuth/UserUpdater.tsx +3 -1
  37. package/src/locales/default/common.ts +29 -8
  38. package/src/app/loading/type.ts +0 -6
@@ -3,12 +3,10 @@
3
3
  import { useRouter } from 'next/navigation';
4
4
  import { memo, useEffect } from 'react';
5
5
 
6
- import { useGlobalStore } from '@/store/global';
7
- import { systemStatusSelectors } from '@/store/global/selectors';
8
6
  import { useUserStore } from '@/store/user';
9
7
  import { authSelectors } from '@/store/user/selectors';
10
8
 
11
- import { AppLoadingStage } from './type';
9
+ import { AppLoadingStage } from '../stage';
12
10
 
13
11
  interface RedirectProps {
14
12
  setLoadingStage: (value: AppLoadingStage) => void;
@@ -22,7 +20,6 @@ const Redirect = memo<RedirectProps>(({ setLoadingStage }) => {
22
20
  s.isUserStateInit,
23
21
  s.isOnboard,
24
22
  ]);
25
- const isPgliteNotEnabled = useGlobalStore(systemStatusSelectors.isPgliteNotEnabled);
26
23
 
27
24
  const navToChat = () => {
28
25
  setLoadingStage(AppLoadingStage.GoToChat);
@@ -30,12 +27,6 @@ const Redirect = memo<RedirectProps>(({ setLoadingStage }) => {
30
27
  };
31
28
 
32
29
  useEffect(() => {
33
- // if pglite is not enabled, redirect to chat
34
- if (isPgliteNotEnabled) {
35
- navToChat();
36
- return;
37
- }
38
-
39
30
  // if user auth state is not ready, wait for loading
40
31
  if (!isLoaded) {
41
32
  setLoadingStage(AppLoadingStage.InitAuth);
@@ -60,9 +51,9 @@ const Redirect = memo<RedirectProps>(({ setLoadingStage }) => {
60
51
  return;
61
52
  }
62
53
 
63
- // finally check the conversation status
54
+ // finally go to chat
64
55
  navToChat();
65
- }, [isUserStateInit, isLoaded, isOnboard, isLogin, isPgliteNotEnabled]);
56
+ }, [isUserStateInit, isLoaded, isOnboard, isLogin]);
66
57
 
67
58
  return null;
68
59
  });
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+
5
+ import { AppLoadingStage } from '../stage';
6
+ import Content from './Content';
7
+ import Redirect from './Redirect';
8
+
9
+ const ServerMode = () => {
10
+ const [loadingStage, setLoadingStage] = useState(AppLoadingStage.Initializing);
11
+
12
+ return (
13
+ <>
14
+ <Content loadingStage={loadingStage} />
15
+ <Redirect setLoadingStage={setLoadingStage} />
16
+ </>
17
+ );
18
+ };
19
+
20
+ ServerMode.displayName = 'ServerMode';
21
+
22
+ export default ServerMode;
@@ -1,21 +1,9 @@
1
- 'use client';
1
+ import { isServerMode } from '@/const/version';
2
2
 
3
- import { useState } from 'react';
3
+ import Client from './Client';
4
+ import Server from './Server';
4
5
 
5
- import { AppLoadingStage } from '@/app/loading/type';
6
-
7
- import Client from './Content';
8
- import Redirect from './Redirect';
9
-
10
- const ScreenLoading = () => {
11
- const [loadingStage, setLoadingStage] = useState(AppLoadingStage.Initializing);
12
- return (
13
- <>
14
- <Client loadingStage={loadingStage} />
15
- <Redirect setLoadingStage={setLoadingStage} />
16
- </>
17
- );
18
- };
6
+ const ScreenLoading = () => (isServerMode ? <Server /> : <Client />);
19
7
 
20
8
  ScreenLoading.displayName = 'ScreenLoading';
21
9
 
@@ -0,0 +1,22 @@
1
+ export enum AppLoadingStage {
2
+ GoToChat = 'goToChat',
3
+ Idle = 'appIdle',
4
+ InitAuth = 'initAuth',
5
+ InitUser = 'initUser',
6
+ Initializing = 'appInitializing',
7
+ }
8
+
9
+ export const SERVER_LOADING_STAGES = [
10
+ AppLoadingStage.Idle,
11
+ AppLoadingStage.Initializing,
12
+ AppLoadingStage.InitAuth,
13
+ AppLoadingStage.InitUser,
14
+ AppLoadingStage.GoToChat,
15
+ ];
16
+
17
+ export const CLIENT_LOADING_STAGES = [
18
+ AppLoadingStage.Idle,
19
+ AppLoadingStage.Initializing,
20
+ AppLoadingStage.InitUser,
21
+ AppLoadingStage.GoToChat,
22
+ ] as string[];
@@ -1,19 +1,20 @@
1
- import { Icon } from '@lobehub/ui';
2
- import { Loader2 } from 'lucide-react';
3
- import { ReactNode, memo } from 'react';
1
+ import React, { memo } from 'react';
4
2
  import { Center, Flexbox } from 'react-layout-kit';
5
3
 
6
4
  import { ProductLogo } from '@/components/Branding';
5
+ import InitProgress, { StageItem } from '@/components/InitProgress';
7
6
 
8
- const FullscreenLoading = memo<{ title?: ReactNode }>(({ title }) => {
7
+ interface FullscreenLoadingProps {
8
+ activeStage: number;
9
+ stages: StageItem[];
10
+ }
11
+
12
+ const FullscreenLoading = memo<FullscreenLoadingProps>(({ activeStage, stages }) => {
9
13
  return (
10
14
  <Flexbox height={'100%'} style={{ position: 'relative', userSelect: 'none' }} width={'100%'}>
11
15
  <Center flex={1} gap={16} width={'100%'}>
12
16
  <ProductLogo size={48} type={'combine'} />
13
- <Center gap={12} horizontal style={{ fontSize: 15, lineHeight: 1.5, opacity: 0.66 }}>
14
- <Icon icon={Loader2} size={{ fontSize: 16 }} spin />
15
- {title}
16
- </Center>
17
+ <InitProgress activeStage={activeStage} stages={stages} />
17
18
  </Center>
18
19
  </Flexbox>
19
20
  );
@@ -0,0 +1,42 @@
1
+ import { Icon } from '@lobehub/ui';
2
+ import { Progress, Typography } from 'antd';
3
+ import { useTheme } from 'antd-style';
4
+ import { Loader2 } from 'lucide-react';
5
+ import { ReactNode, memo } from 'react';
6
+ import { Center, Flexbox } from 'react-layout-kit';
7
+
8
+ export interface StageObjectItem {
9
+ icon?: ReactNode;
10
+ text: string;
11
+ }
12
+ export type StageItem = string | StageObjectItem;
13
+
14
+ interface InitingProps {
15
+ activeStage: number;
16
+ stages: StageItem[];
17
+ }
18
+
19
+ const InitProgress = memo<InitingProps>(({ activeStage, stages }) => {
20
+ const theme = useTheme();
21
+
22
+ const outStage = stages[activeStage];
23
+ const percent = (activeStage / (stages.length - 1)) * 100;
24
+
25
+ const stage = typeof outStage === 'string' ? { text: outStage } : outStage;
26
+
27
+ return (
28
+ <Center gap={8} width={180}>
29
+ <Progress
30
+ percent={parseInt(percent.toFixed(0))}
31
+ showInfo={false}
32
+ strokeColor={theme.colorPrimary}
33
+ />
34
+ <Flexbox align={'center'} gap={4} horizontal>
35
+ {stage?.icon ? stage?.icon : <Icon icon={Loader2} spin />}
36
+ <Typography.Text type={'secondary'}>{stage?.text}</Typography.Text>
37
+ </Flexbox>
38
+ </Center>
39
+ );
40
+ });
41
+
42
+ export default InitProgress;
@@ -1,13 +1,26 @@
1
- 'use client';
2
-
1
+ import { Icon } from '@lobehub/ui';
2
+ import { Loader2 } from 'lucide-react';
3
+ import { DynamicOptions } from 'next/dist/shared/lib/dynamic';
4
+ import { memo } from 'react';
3
5
  import { useTranslation } from 'react-i18next';
6
+ import { Center, Flexbox } from 'react-layout-kit';
4
7
 
5
- import FullscreenLoading from '@/components/FullscreenLoading';
8
+ import { ProductLogo } from '@/components/Branding';
6
9
 
7
- const MobileSwitchLoading = () => {
10
+ // @ts-expect-error
11
+ const MobileSwitchLoading: DynamicOptions['loading'] = memo(() => {
8
12
  const { t } = useTranslation('common');
9
-
10
- return <FullscreenLoading title={t('layoutInitializing')} />;
11
- };
13
+ return (
14
+ <Flexbox height={'100%'} style={{ position: 'relative', userSelect: 'none' }} width={'100%'}>
15
+ <Center flex={1} gap={16} width={'100%'}>
16
+ <ProductLogo size={48} type={'combine'} />
17
+ <Center gap={12} horizontal style={{ fontSize: 15, lineHeight: 1.5, opacity: 0.66 }}>
18
+ <Icon icon={Loader2} size={{ fontSize: 16 }} spin />
19
+ {t('layoutInitializing')}
20
+ </Center>
21
+ </Center>
22
+ </Flexbox>
23
+ );
24
+ });
12
25
 
13
26
  export default MobileSwitchLoading;
@@ -10,6 +10,8 @@ import { LobeUser } from '@/types/user';
10
10
  // update the user data into the context
11
11
  const UserUpdater = memo(() => {
12
12
  const { data: session, status } = useSession();
13
+ const isLoaded = status !== 'loading';
14
+
13
15
  const isSignedIn = (status === 'authenticated' && session && !!session.user) || false;
14
16
 
15
17
  const nextUser = session?.user;
@@ -22,7 +24,7 @@ const UserUpdater = memo(() => {
22
24
  id: nextUser?.id,
23
25
  } as LobeUser;
24
26
 
25
- useStoreUpdater('isLoaded', true);
27
+ useStoreUpdater('isLoaded', isLoaded);
26
28
  useStoreUpdater('user', lobeUser);
27
29
  useStoreUpdater('isSignedIn', isSignedIn);
28
30
 
@@ -11,10 +11,17 @@ export default {
11
11
  },
12
12
  },
13
13
  appLoading: {
14
- goToChat: '(4/4) 对话页面加载中...',
15
- initAuth: '(2/4) 鉴权服务初始化...',
16
- initUser: '(3/4) 用户状态初始化...',
17
- initializing: '(1/4) 应用启动中...',
14
+ appIdle: '准备启动',
15
+ appInitializing: '应用启动中...',
16
+ finished: '数据库初始化完成',
17
+ goToChat: '对话页面加载中...',
18
+ initAuth: '鉴权服务初始化...',
19
+ initUser: '用户状态初始化...',
20
+ initializing: 'PGlite 数据库初始化...',
21
+ loadingDependencies: '初始化依赖...',
22
+ loadingWasm: '加载 WASM 模块...',
23
+ migrating: '执行数据表迁移...',
24
+ ready: '数据库已就绪',
18
25
  },
19
26
  autoGenerate: '自动补全',
20
27
  autoGenerateTooltip: '基于提示词自动补全助手描述',
@@ -40,14 +47,28 @@ export default {
40
47
  error: '发生错误,请重试',
41
48
  idle: '等待初始化...',
42
49
  initializing: '正在初始化...',
43
- loadingDependencies: `加载依赖中({{progress}}%)...`,
44
- loadingWasmModule: '加载 WASM 模块中({{progress}}%)...',
45
- migrating: '正在迁移数据...',
50
+ loadingDependencies: '加载依赖中...',
51
+ loadingWasmModule: '加载 WASM 模块中...',
52
+ migrating: '执行数据表迁移...',
46
53
  ready: '数据库已就绪',
47
54
  },
48
55
  modal: {
49
- desc: '启用 PGlite 客户端数据库,在你的浏览器中持久存储聊天数据,并使用知识库等进阶特性',
56
+ desc: '立即启用下一代客户端数据库。在你的浏览器中持久存储聊天数据,并使用知识库等进阶特性。',
50
57
  enable: '立即启用',
58
+ features: {
59
+ knowledgeBase: {
60
+ desc: '沉淀你的个人知识库,并与你的助手轻松开启知识库对话(即将上线)',
61
+ title: '支持知识库对话,开启第二大脑',
62
+ },
63
+ localFirst: {
64
+ desc: '聊天数据完全存储在浏览器中,你的数据始终在你的掌握。',
65
+ title: '本地优先,隐私至上',
66
+ },
67
+ pglite: {
68
+ desc: '基于 PGlite 构建,原生支持 AI Native 高阶特性(向量检索)',
69
+ title: '新一代客户端存储架构',
70
+ },
71
+ },
51
72
  init: {
52
73
  desc: '正在初始化数据库,视网络差异可能会用时 5~30 秒不等',
53
74
  title: '正在初始化 PGlite 数据库',
@@ -1,6 +0,0 @@
1
- export enum AppLoadingStage {
2
- GoToChat = 'goToChat',
3
- InitAuth = 'initAuth',
4
- InitUser = 'initUser',
5
- Initializing = 'initializing',
6
- }