@lobehub/chat 1.36.20 → 1.36.21

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 (35) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/changelog/v1.json +5 -0
  3. package/locales/ar/welcome.json +0 -5
  4. package/locales/bg-BG/welcome.json +0 -5
  5. package/locales/de-DE/welcome.json +0 -5
  6. package/locales/en-US/welcome.json +0 -5
  7. package/locales/es-ES/welcome.json +0 -5
  8. package/locales/fa-IR/welcome.json +0 -5
  9. package/locales/fr-FR/welcome.json +0 -5
  10. package/locales/it-IT/welcome.json +0 -5
  11. package/locales/ja-JP/welcome.json +0 -5
  12. package/locales/ko-KR/welcome.json +0 -5
  13. package/locales/nl-NL/welcome.json +0 -5
  14. package/locales/pl-PL/welcome.json +0 -5
  15. package/locales/pt-BR/welcome.json +0 -5
  16. package/locales/ru-RU/welcome.json +0 -5
  17. package/locales/tr-TR/welcome.json +0 -5
  18. package/locales/vi-VN/welcome.json +0 -5
  19. package/locales/zh-CN/welcome.json +0 -5
  20. package/locales/zh-TW/welcome.json +0 -5
  21. package/package.json +1 -1
  22. package/src/app/loading/Redirect.tsx +4 -9
  23. package/src/components/Branding/index.ts +0 -1
  24. package/src/locales/default/welcome.ts +0 -5
  25. package/src/server/sitemap.ts +0 -1
  26. package/src/app/(main)/welcome/_layout/Desktop.tsx +0 -42
  27. package/src/app/(main)/welcome/_layout/Mobile.tsx +0 -12
  28. package/src/app/(main)/welcome/features/Actions.test.tsx +0 -77
  29. package/src/app/(main)/welcome/features/Actions.tsx +0 -44
  30. package/src/app/(main)/welcome/features/Hero.tsx +0 -65
  31. package/src/app/(main)/welcome/layout.tsx +0 -10
  32. package/src/app/(main)/welcome/page.tsx +0 -42
  33. package/src/components/Branding/WelcomeLogo/Custom.tsx +0 -41
  34. package/src/components/Branding/WelcomeLogo/LobeChat.tsx +0 -32
  35. package/src/components/Branding/WelcomeLogo/index.tsx +0 -16
package/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.36.21](https://github.com/lobehub/lobe-chat/compare/v1.36.20...v1.36.21)
6
+
7
+ <sup>Released on **2024-12-13**</sup>
8
+
9
+ <br/>
10
+
11
+ <details>
12
+ <summary><kbd>Improvements and Fixes</kbd></summary>
13
+
14
+ </details>
15
+
16
+ <div align="right">
17
+
18
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
19
+
20
+ </div>
21
+
5
22
  ### [Version 1.36.20](https://github.com/lobehub/lobe-chat/compare/v1.36.19...v1.36.20)
6
23
 
7
24
  <sup>Released on **2024-12-13**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,9 @@
1
1
  [
2
+ {
3
+ "children": {},
4
+ "date": "2024-12-13",
5
+ "version": "1.36.21"
6
+ },
2
7
  {
3
8
  "children": {
4
9
  "improvements": [
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "استيراد التكوين",
4
- "market": "تسوق في السوق",
5
- "start": "ابدأ الآن"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "تغيير",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Импортирай конфигурация",
4
- "market": "Пазар",
5
- "start": "Започни сега"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Смени",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Konfiguration importieren",
4
- "market": "Markt durchstöbern",
5
- "start": "Jetzt starten"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Ersetzen",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Import Configuration",
4
- "market": "Visit Market",
5
- "start": "Start Now"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Replace Batch",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Importar configuración",
4
- "market": "Explorar el mercado",
5
- "start": "Comenzar ahora"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Cambiar grupo",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "وارد کردن تنظیمات",
4
- "market": "بازدید از بازار",
5
- "start": "شروع کن"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "تغییر دسته",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Importer la configuration",
4
- "market": "Parcourir le marché",
5
- "start": "Démarrer maintenant"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Remplacer",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Importa configurazione",
4
- "market": "Esplora il mercato",
5
- "start": "Inizia subito"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Cambia gruppo",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "設定をインポート",
4
- "market": "市場を見る",
5
- "start": "すぐに開始"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "別のグループ",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "구성 가져오기",
4
- "market": "시장 구경하기",
5
- "start": "지금 시작"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "다른 것으로 바꾸기",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Importeer configuratie",
4
- "market": "Verken de markt",
5
- "start": "Nu beginnen"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Vervang een groep",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Importuj konfigurację",
4
- "market": "Przeglądaj rynek",
5
- "start": "Rozpocznij teraz"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Zmień",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Importar configuração",
4
- "market": "Explorar o mercado",
5
- "start": "Começar agora"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Trocar",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Импорт конфига",
4
- "market": "Посетить рынок",
5
- "start": "Начать"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Заменить",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "İçe Aktar",
4
- "market": "Pazara Göz At",
5
- "start": "Başla"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Başka bir grup",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "Nhập Cấu Hình",
4
- "market": "Thăm Thị trường",
5
- "start": "Bắt Đầu Ngay"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "Thay đổi",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "导入配置",
4
- "market": "逛逛市场",
5
- "start": "立即开始"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "换一批",
@@ -1,9 +1,4 @@
1
1
  {
2
- "button": {
3
- "import": "匯入設定檔",
4
- "market": "逛逛市場",
5
- "start": "馬上開始"
6
- },
7
2
  "guide": {
8
3
  "agents": {
9
4
  "replaceBtn": "換一批",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.36.20",
3
+ "version": "1.36.21",
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",
@@ -8,12 +8,11 @@ import { authSelectors } from '@/store/user/selectors';
8
8
 
9
9
  const Redirect = memo(() => {
10
10
  const router = useRouter();
11
- const [isLogin, isLoaded, isUserStateInit, isUserHasConversation, isOnboard] = useUserStore(
11
+ const [isLogin, isLoaded, isUserStateInit, isOnboard] = useUserStore(
12
12
  (s) => [
13
13
  authSelectors.isLogin(s),
14
14
  authSelectors.isLoaded(s),
15
15
  s.isUserStateInit,
16
- s.isUserHasConversation,
17
16
  s.isOnboard,
18
17
  ],
19
18
  );
@@ -24,7 +23,7 @@ const Redirect = memo(() => {
24
23
 
25
24
  // this mean user is definitely not login
26
25
  if (!isLogin) {
27
- router.replace('/welcome');
26
+ router.replace('/chat');
28
27
  return;
29
28
  }
30
29
 
@@ -38,12 +37,8 @@ const Redirect = memo(() => {
38
37
  }
39
38
 
40
39
  // finally check the conversation status
41
- if (isUserHasConversation) {
42
- router.replace('/chat');
43
- } else {
44
- router.replace('/welcome');
45
- }
46
- }, [isUserStateInit, isLoaded, isUserHasConversation, isOnboard, isLogin]);
40
+ router.replace('/chat');
41
+ }, [isUserStateInit, isLoaded, isOnboard, isLogin]);
47
42
 
48
43
  return null;
49
44
  });
@@ -1,3 +1,2 @@
1
1
  export { OrgBrand } from './OrgBrand';
2
2
  export { ProductLogo } from './ProductLogo';
3
- export { WelcomeLogo } from './WelcomeLogo';
@@ -1,9 +1,4 @@
1
1
  export default {
2
- button: {
3
- import: '导入配置',
4
- market: '逛逛市场',
5
- start: '立即开始',
6
- },
7
2
  guide: {
8
3
  agents: {
9
4
  replaceBtn: '换一批',
@@ -201,7 +201,6 @@ export class Sitemap {
201
201
  return [
202
202
  ...this._genSitemap('/', { noLocales: true }),
203
203
  ...this._genSitemap('/chat', { noLocales: true }),
204
- ...this._genSitemap('/welcome', { noLocales: true }),
205
204
  /* ↓ cloud slot ↓ */
206
205
 
207
206
  /* ↑ cloud slot ↑ */
@@ -1,42 +0,0 @@
1
- import { GridShowcase } from '@lobehub/ui';
2
- import { PropsWithChildren } from 'react';
3
- import { Flexbox } from 'react-layout-kit';
4
-
5
- import { ORG_NAME } from '@/const/branding';
6
- import { isCustomORG } from '@/const/version';
7
- import Follow from '@/features/Follow';
8
-
9
- const COPYRIGHT = `© ${new Date().getFullYear()} ${ORG_NAME}`;
10
-
11
- const DesktopLayout = ({ children }: PropsWithChildren) => {
12
- return (
13
- <>
14
- <Flexbox
15
- align={'center'}
16
- height={'100%'}
17
- justify={'space-between'}
18
- padding={16}
19
- style={{ overflow: 'hidden', position: 'relative' }}
20
- width={'100%'}
21
- >
22
- <div />
23
- <GridShowcase
24
- innerProps={{ gap: 24 }}
25
- style={{ maxHeight: 'calc(100% - 104px)', maxWidth: 1024 }}
26
- width={'100%'}
27
- >
28
- {children}
29
- </GridShowcase>
30
- <Flexbox align={'center'} horizontal justify={'space-between'}>
31
- <span style={{ opacity: 0.5 }}>{COPYRIGHT}</span>
32
- {isCustomORG ? <div /> : <Follow />}
33
- </Flexbox>
34
- </Flexbox>
35
- {/* ↓ cloud slot ↓ */}
36
-
37
- {/* ↑ cloud slot ↑ */}
38
- </>
39
- );
40
- };
41
-
42
- export default DesktopLayout;
@@ -1,12 +0,0 @@
1
- import { PropsWithChildren } from 'react';
2
- import { Center } from 'react-layout-kit';
3
-
4
- const MobileLayout = ({ children }: PropsWithChildren) => {
5
- return (
6
- <Center gap={16} style={{ height: '100%', paddingInline: 16 }}>
7
- {children}
8
- </Center>
9
- );
10
- };
11
-
12
- export default MobileLayout;
@@ -1,77 +0,0 @@
1
- import { act, cleanup, fireEvent, render, renderHook, screen } from '@testing-library/react';
2
- import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
3
-
4
- import {
5
- Provider,
6
- createServerConfigStore,
7
- initServerConfigStore,
8
- } from '@/store/serverConfig/store';
9
-
10
- import Actions from './Actions';
11
-
12
- beforeAll(() => {
13
- initServerConfigStore({ featureFlags: { market: true } });
14
- });
15
-
16
- beforeEach(() => {
17
- vi.clearAllMocks();
18
- });
19
-
20
- afterEach(() => {
21
- createServerConfigStore().setState({ featureFlags: { market: true } });
22
- cleanup();
23
- });
24
-
25
- vi.mock('next/link', () => ({
26
- default: vi.fn(({ children }: { children: React.ReactNode }) => <div>{children}</div>),
27
- }));
28
-
29
- vi.mock('react-i18next', () => ({
30
- useTranslation: vi.fn(() => ({
31
- t: vi.fn((key) => key),
32
- })),
33
- }));
34
-
35
- const push = vi.fn();
36
-
37
- vi.mock('next/navigation', () => ({
38
- useRouter: vi.fn(() => ({
39
- push,
40
- })),
41
- }));
42
-
43
- const renderActions = (props: { mobile?: boolean }) => {
44
- render(
45
- <Provider createStore={createServerConfigStore}>
46
- <Actions {...props} />
47
- </Provider>,
48
- );
49
- };
50
-
51
- describe('Welcome Actions', () => {
52
- it('should render Start and Market button', () => {
53
- renderActions({});
54
-
55
- expect(screen.getByText('button.start')).toBeInTheDocument();
56
- expect(screen.getByText('button.market')).toBeInTheDocument();
57
- });
58
-
59
- it('should render Start when `-market` is set', () => {
60
- act(() => {
61
- createServerConfigStore().setState({ featureFlags: { market: false } });
62
- });
63
-
64
- renderActions({});
65
-
66
- expect(screen.getByText('button.start')).toBeInTheDocument();
67
- expect(screen.queryByText('button.market')).not.toBeInTheDocument();
68
- });
69
-
70
- it('Clicking start button should push to `/chat`', () => {
71
- renderActions({});
72
-
73
- fireEvent.click(screen.getByText('button.start'));
74
-
75
- expect(push).toHaveBeenCalledWith('/chat');
76
- });
77
- });
@@ -1,44 +0,0 @@
1
- 'use client';
2
-
3
- import { Icon } from '@lobehub/ui';
4
- import { Button } from 'antd';
5
- import { SendHorizonal } from 'lucide-react';
6
- import Link from 'next/link';
7
- import { useRouter } from 'next/navigation';
8
- import { memo } from 'react';
9
- import { useTranslation } from 'react-i18next';
10
- import { Flexbox } from 'react-layout-kit';
11
-
12
- import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
13
-
14
- const Actions = memo<{ mobile?: boolean }>(({ mobile }) => {
15
- const { t } = useTranslation('welcome');
16
- const router = useRouter();
17
- const { showMarket } = useServerConfigStore(featureFlagsSelectors);
18
-
19
- return (
20
- <Flexbox gap={16} horizontal={!mobile} justify={'center'} width={'100%'} wrap={'wrap'}>
21
- {showMarket && (
22
- <Link href={'/discover'}>
23
- <Button block={mobile} size={'large'} style={{ minWidth: 160 }} type={'default'}>
24
- {t('button.market')}
25
- </Button>
26
- </Link>
27
- )}
28
- <Button
29
- block={mobile}
30
- onClick={() => router.push('/chat')}
31
- size={'large'}
32
- style={{ minWidth: 160 }}
33
- type={'primary'}
34
- >
35
- <Flexbox align={'center'} gap={4} horizontal justify={'center'}>
36
- {t('button.start')}
37
- <Icon icon={SendHorizonal} />
38
- </Flexbox>
39
- </Button>
40
- </Flexbox>
41
- );
42
- });
43
-
44
- export default Actions;
@@ -1,65 +0,0 @@
1
- 'use client';
2
-
3
- import { createStyles } from 'antd-style';
4
- import { rgba } from 'polished';
5
- import { memo } from 'react';
6
- import { useTranslation } from 'react-i18next';
7
- import { Flexbox } from 'react-layout-kit';
8
-
9
- import { BRANDING_NAME } from '@/const/branding';
10
-
11
- const useStyles = createStyles(({ css, token }) => {
12
- return {
13
- desc: css`
14
- font-size: min(24px, 4vw);
15
- font-weight: 400;
16
- color: ${rgba(token.colorText, 0.8)};
17
- text-align: center;
18
- text-wrap: balance;
19
- `,
20
- title: css`
21
- margin-block-end: 0;
22
-
23
- font-size: min(56px, 7vw);
24
- font-weight: 800;
25
- line-height: 1;
26
- text-align: center;
27
- text-wrap: balance;
28
- `,
29
- };
30
- });
31
-
32
- const Hero = memo(() => {
33
- const { styles } = useStyles();
34
-
35
- const { t } = useTranslation('welcome');
36
-
37
- return (
38
- <>
39
- <Flexbox
40
- align={'center'}
41
- as={'h1'}
42
- className={styles.title}
43
- gap={16}
44
- horizontal
45
- justify={'center'}
46
- wrap={'wrap'}
47
- >
48
- <strong style={{ fontSize: 'min(56px, 8vw)' }}>{BRANDING_NAME}</strong>
49
- <span>{t('slogan.title')}</span>
50
- </Flexbox>
51
- <Flexbox
52
- align={'center'}
53
- as={'h2'}
54
- className={styles.desc}
55
- horizontal
56
- justify={'center'}
57
- wrap={'wrap'}
58
- >
59
- {t('slogan.desc1')}
60
- </Flexbox>
61
- </>
62
- );
63
- });
64
-
65
- export default Hero;
@@ -1,10 +0,0 @@
1
- import ServerLayout from '@/components/server/ServerLayout';
2
-
3
- import Desktop from './_layout/Desktop';
4
- import Mobile from './_layout/Mobile';
5
-
6
- const WelcomeLayout = ServerLayout({ Desktop, Mobile });
7
-
8
- WelcomeLayout.displayName = 'WelcomeLayout';
9
-
10
- export default WelcomeLayout;
@@ -1,42 +0,0 @@
1
- import { WelcomeLogo } from '@/components/Branding';
2
- import StructuredData from '@/components/StructuredData';
3
- import { BRANDING_NAME } from '@/const/branding';
4
- import { ldModule } from '@/server/ld';
5
- import { metadataModule } from '@/server/metadata';
6
- import { translation } from '@/server/translation';
7
- import { isMobileDevice } from '@/utils/server/responsive';
8
-
9
- import Actions from './features/Actions';
10
- import Hero from './features/Hero';
11
-
12
- export const generateMetadata = async () => {
13
- const { t } = await translation('metadata');
14
- return metadataModule.generate({
15
- description: t('welcome.description', { appName: BRANDING_NAME }),
16
- title: t('welcome.title', { appName: BRANDING_NAME }),
17
- url: '/welcome',
18
- });
19
- };
20
-
21
- const Page = async () => {
22
- const mobile = isMobileDevice();
23
- const { t } = await translation('metadata');
24
- const ld = ldModule.generate({
25
- description: t('welcome.description', { appName: BRANDING_NAME }),
26
- title: t('welcome.title', { appName: BRANDING_NAME }),
27
- url: '/welcome',
28
- });
29
-
30
- return (
31
- <>
32
- <StructuredData ld={ld} />
33
- <WelcomeLogo mobile={mobile} />
34
- <Hero />
35
- <Actions mobile={mobile} />
36
- </>
37
- );
38
- };
39
-
40
- Page.displayName = 'Welcome';
41
-
42
- export default Page;
@@ -1,41 +0,0 @@
1
- 'use client';
2
-
3
- import Image from 'next/image';
4
- import { memo } from 'react';
5
- import { Center } from 'react-layout-kit';
6
-
7
- import { BRANDING_LOGO_URL, BRANDING_NAME } from '@/const/branding';
8
-
9
- const WelcomeLogo = memo<{ mobile?: boolean }>(({ mobile }) => {
10
- return mobile ? (
11
- <Center height={240} width={240}>
12
- <Image
13
- alt={BRANDING_NAME}
14
- height={240}
15
- src={BRANDING_LOGO_URL}
16
- unoptimized={true}
17
- width={240}
18
- />
19
- </Center>
20
- ) : (
21
- <Center
22
- style={{
23
- height: `min(482px, 40vw)`,
24
- marginBottom: '-10%',
25
- marginTop: '-20%',
26
- position: 'relative',
27
- width: `min(976px, 80vw)`,
28
- }}
29
- >
30
- <Image
31
- alt={BRANDING_NAME}
32
- height={240}
33
- src={BRANDING_LOGO_URL}
34
- unoptimized={true}
35
- width={240}
36
- />
37
- </Center>
38
- );
39
- });
40
-
41
- export default WelcomeLogo;
@@ -1,32 +0,0 @@
1
- 'use client';
2
-
3
- import dynamic from 'next/dynamic';
4
- import { memo } from 'react';
5
- import { Center } from 'react-layout-kit';
6
-
7
- const LogoThree = dynamic(() => import('@lobehub/ui/es/brand/LogoThree'), { ssr: false });
8
- const LogoSpline = dynamic(() => import('@lobehub/ui/es/brand/LogoThree/LogoSpline'), {
9
- ssr: false,
10
- });
11
-
12
- const WelcomeLogo = memo<{ mobile?: boolean }>(({ mobile }) => {
13
- return mobile ? (
14
- <Center height={240} width={240}>
15
- <LogoThree size={240} />
16
- </Center>
17
- ) : (
18
- <Center
19
- style={{
20
- height: `min(482px, 40vw)`,
21
- marginBottom: '-10%',
22
- marginTop: '-20%',
23
- position: 'relative',
24
- width: `min(976px, 80vw)`,
25
- }}
26
- >
27
- <LogoSpline height={'min(482px, 40vw)'} width={'min(976px, 80vw)'} />
28
- </Center>
29
- );
30
- });
31
-
32
- export default WelcomeLogo;
@@ -1,16 +0,0 @@
1
- 'use client';
2
-
3
- import { memo } from 'react';
4
-
5
- import { isCustomBranding } from '@/const/version';
6
-
7
- import CustomLogo from './Custom';
8
- import LobeChat from './LobeChat';
9
-
10
- export const WelcomeLogo = memo<{ mobile?: boolean }>(({ mobile }) => {
11
- if (isCustomBranding) {
12
- return <CustomLogo mobile={mobile} />;
13
- }
14
-
15
- return <LobeChat mobile={mobile} />;
16
- });