@lobehub/chat 1.39.2 → 1.40.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.
- package/.env.example +19 -8
- package/.eslintignore +1 -1
- package/CHANGELOG.md +58 -0
- package/changelog/v1.json +21 -0
- package/docs/.cdn.cache.json +25 -0
- package/docs/changelog/2023-09-09-plugin-system.mdx +1 -1
- package/docs/changelog/2023-09-09-plugin-system.zh-CN.mdx +1 -1
- package/docs/changelog/2024-09-20-artifacts.mdx +1 -1
- package/docs/changelog/2024-09-20-artifacts.zh-CN.mdx +1 -1
- package/docs/changelog/2024-10-27-pin-assistant.mdx +2 -2
- package/docs/changelog/2024-10-27-pin-assistant.zh-CN.mdx +2 -2
- package/docs/changelog/2024-11-06-share-text-json.mdx +2 -2
- package/docs/changelog/2024-11-06-share-text-json.zh-CN.mdx +2 -2
- package/docs/changelog/index.json +16 -16
- package/locales/ar/changelog.json +18 -0
- package/locales/ar/common.json +1 -0
- package/locales/ar/metadata.json +4 -0
- package/locales/bg-BG/changelog.json +18 -0
- package/locales/bg-BG/common.json +1 -0
- package/locales/bg-BG/metadata.json +4 -0
- package/locales/de-DE/changelog.json +18 -0
- package/locales/de-DE/common.json +1 -0
- package/locales/de-DE/metadata.json +4 -0
- package/locales/en-US/changelog.json +18 -0
- package/locales/en-US/common.json +1 -0
- package/locales/en-US/metadata.json +4 -0
- package/locales/es-ES/changelog.json +18 -0
- package/locales/es-ES/common.json +1 -0
- package/locales/es-ES/metadata.json +4 -0
- package/locales/fa-IR/changelog.json +18 -0
- package/locales/fa-IR/common.json +1 -0
- package/locales/fa-IR/metadata.json +4 -0
- package/locales/fr-FR/changelog.json +18 -0
- package/locales/fr-FR/common.json +1 -0
- package/locales/fr-FR/metadata.json +4 -0
- package/locales/it-IT/changelog.json +18 -0
- package/locales/it-IT/common.json +1 -0
- package/locales/it-IT/metadata.json +4 -0
- package/locales/ja-JP/changelog.json +18 -0
- package/locales/ja-JP/common.json +1 -0
- package/locales/ja-JP/metadata.json +4 -0
- package/locales/ko-KR/changelog.json +18 -0
- package/locales/ko-KR/common.json +1 -0
- package/locales/ko-KR/metadata.json +4 -0
- package/locales/nl-NL/changelog.json +18 -0
- package/locales/nl-NL/common.json +1 -0
- package/locales/nl-NL/metadata.json +4 -0
- package/locales/pl-PL/changelog.json +18 -0
- package/locales/pl-PL/common.json +1 -0
- package/locales/pl-PL/metadata.json +4 -0
- package/locales/pt-BR/changelog.json +18 -0
- package/locales/pt-BR/common.json +1 -0
- package/locales/pt-BR/metadata.json +4 -0
- package/locales/ru-RU/changelog.json +18 -0
- package/locales/ru-RU/common.json +1 -0
- package/locales/ru-RU/metadata.json +4 -0
- package/locales/tr-TR/changelog.json +18 -0
- package/locales/tr-TR/common.json +1 -0
- package/locales/tr-TR/metadata.json +4 -0
- package/locales/vi-VN/changelog.json +18 -0
- package/locales/vi-VN/common.json +1 -0
- package/locales/vi-VN/metadata.json +4 -0
- package/locales/zh-CN/changelog.json +18 -0
- package/locales/zh-CN/common.json +1 -0
- package/locales/zh-CN/metadata.json +4 -0
- package/locales/zh-TW/changelog.json +18 -0
- package/locales/zh-TW/common.json +1 -0
- package/locales/zh-TW/metadata.json +4 -0
- package/package.json +6 -1
- package/scripts/cdnWorkflow/index.ts +217 -0
- package/scripts/cdnWorkflow/optimized.ts +21 -0
- package/scripts/cdnWorkflow/s3/index.ts +120 -0
- package/scripts/cdnWorkflow/s3/types.ts +25 -0
- package/scripts/cdnWorkflow/s3/utils.ts +106 -0
- package/scripts/cdnWorkflow/uploader.ts +73 -0
- package/scripts/cdnWorkflow/utils.ts +93 -0
- package/src/app/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +25 -12
- package/src/app/(main)/(mobile)/me/(home)/features/useCategory.tsx +19 -9
- package/src/app/(main)/(mobile)/me/(home)/loading.tsx +1 -1
- package/src/app/(main)/(mobile)/me/data/loading.tsx +1 -1
- package/src/app/(main)/(mobile)/me/profile/loading.tsx +1 -1
- package/src/app/(main)/(mobile)/me/settings/loading.tsx +1 -1
- package/src/app/(main)/_layout/Desktop.tsx +4 -1
- package/src/app/(main)/_layout/Mobile.tsx +2 -1
- package/src/app/(main)/changelog/_layout/Desktop.tsx +25 -0
- package/src/app/(main)/changelog/_layout/Mobile/Header.tsx +33 -0
- package/src/app/(main)/changelog/_layout/Mobile/index.tsx +21 -0
- package/src/app/(main)/changelog/error.tsx +5 -0
- package/src/app/(main)/changelog/features/GridLayout.tsx +22 -0
- package/src/app/(main)/changelog/features/Hero.tsx +40 -0
- package/src/app/(main)/changelog/features/Post.tsx +56 -0
- package/src/app/(main)/changelog/features/PublishedTime.tsx +50 -0
- package/src/app/(main)/changelog/features/VersionTag.tsx +27 -0
- package/src/app/(main)/changelog/layout.tsx +10 -0
- package/src/app/(main)/changelog/loading.tsx +3 -0
- package/src/app/(main)/changelog/modal/page.tsx +23 -0
- package/src/app/(main)/changelog/not-found.tsx +3 -0
- package/src/app/(main)/changelog/page.tsx +73 -0
- package/src/app/(main)/chat/(workspace)/@portal/default.tsx +1 -1
- package/src/app/(main)/chat/(workspace)/@portal/loading.tsx +1 -1
- package/src/app/(main)/chat/(workspace)/page.tsx +9 -2
- package/src/app/(main)/chat/@session/default.tsx +3 -2
- package/src/app/(main)/chat/loading.tsx +1 -1
- package/src/app/(main)/chat/settings/loading.tsx +1 -1
- package/src/app/(main)/discover/loading.tsx +1 -1
- package/src/app/(main)/files/loading.tsx +2 -22
- package/src/app/(main)/profile/loading.tsx +1 -1
- package/src/app/(main)/repos/[id]/evals/dataset/page.tsx +1 -1
- package/src/app/(main)/repos/[id]/evals/evaluation/page.tsx +1 -1
- package/src/app/(main)/settings/@category/default.tsx +6 -2
- package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +1 -1
- package/src/app/(main)/settings/about/features/Version.tsx +2 -2
- package/src/app/(main)/settings/loading.tsx +2 -8
- package/src/app/@modal/(.)changelog/modal/features/Cover.tsx +48 -0
- package/src/app/@modal/(.)changelog/modal/features/Hero.tsx +29 -0
- package/src/app/@modal/(.)changelog/modal/features/Pagination.tsx +54 -0
- package/src/app/@modal/(.)changelog/modal/features/Post.tsx +57 -0
- package/src/app/@modal/(.)changelog/modal/features/PublishedTime.tsx +50 -0
- package/src/app/@modal/(.)changelog/modal/features/ReadDetail.tsx +94 -0
- package/src/app/@modal/(.)changelog/modal/features/UpdateChangelogStatus.tsx +21 -0
- package/src/app/@modal/(.)changelog/modal/features/VersionTag.tsx +27 -0
- package/src/app/@modal/(.)changelog/modal/layout.tsx +39 -0
- package/src/app/@modal/(.)changelog/modal/loading.tsx +10 -0
- package/src/app/@modal/(.)changelog/modal/page.tsx +37 -0
- package/src/app/@modal/(.)settings/modal/layout.tsx +19 -16
- package/src/app/@modal/_layout/ModalLayout.tsx +63 -0
- package/src/app/@modal/chat/(.)settings/modal/layout.tsx +20 -17
- package/src/app/@modal/layout.tsx +5 -69
- package/src/app/loading/Client/Content.tsx +1 -1
- package/src/app/loading/Server/Content.tsx +1 -1
- package/src/components/Loading/BrandTextLoading/LobeChatText/SVG.tsx +44 -0
- package/src/components/Loading/BrandTextLoading/LobeChatText/index.tsx +6 -0
- package/src/components/Loading/BrandTextLoading/LobeChatText/style.css +32 -0
- package/src/components/Loading/BrandTextLoading/index.tsx +11 -0
- package/src/components/{SkeletonLoading → Loading/SkeletonLoading}/index.tsx +1 -1
- package/src/components/mdx/Image.tsx +50 -0
- package/src/components/mdx/index.tsx +2 -0
- package/src/const/url.ts +1 -0
- package/src/features/ChangelogModal/index.tsx +22 -0
- package/src/features/FileViewer/Renderer/TXT/index.tsx +1 -1
- package/src/features/Portal/FilePreview/Body/index.tsx +1 -1
- package/src/features/Portal/Home/Body/Files/FileList/index.tsx +1 -1
- package/src/features/Setting/Footer.tsx +3 -1
- package/src/features/Setting/SettingContainer.tsx +1 -0
- package/src/features/User/UserPanel/useMenu.tsx +50 -46
- package/src/features/User/__tests__/useMenu.test.tsx +7 -6
- package/src/hooks/useInterceptingRoutes.ts +1 -6
- package/src/hooks/useShare.tsx +1 -0
- package/src/locales/default/changelog.ts +18 -0
- package/src/locales/default/common.ts +1 -0
- package/src/locales/default/index.ts +2 -0
- package/src/locales/default/metadata.ts +4 -0
- package/src/server/metadata.ts +5 -3
- package/src/server/routers/edge/appStatus.ts +3 -0
- package/src/server/routers/edge/index.ts +2 -0
- package/src/server/routers/lambda/agent.ts +1 -1
- package/src/server/services/changelog/index.test.ts +310 -0
- package/src/server/services/changelog/index.ts +196 -0
- package/src/server/services/discover/index.test.ts +0 -1
- package/src/server/sitemap.ts +4 -1
- package/src/services/__tests__/chat.test.ts +1 -1
- package/src/services/__tests__/global.test.ts +5 -2
- package/src/services/_auth.ts +1 -1
- package/src/services/agent.ts +25 -21
- package/src/services/chat.ts +2 -2
- package/src/services/file/ClientS3/index.ts +6 -6
- package/src/services/file/client.ts +14 -15
- package/src/services/file/server.ts +20 -25
- package/src/services/global.ts +2 -2
- package/src/services/import/client.ts +6 -5
- package/src/services/import/server.ts +6 -5
- package/src/services/import/type.ts +7 -0
- package/src/services/knowledgeBase.ts +19 -19
- package/src/services/message/_deprecated.ts +5 -0
- package/src/services/message/client.ts +52 -48
- package/src/services/message/server.ts +50 -53
- package/src/services/message/type.ts +2 -2
- package/src/services/plugin/client.ts +16 -22
- package/src/services/plugin/server.ts +15 -19
- package/src/services/rag.ts +18 -18
- package/src/services/ragEval.ts +29 -26
- package/src/services/session/_deprecated.ts +2 -2
- package/src/services/session/client.ts +55 -81
- package/src/services/session/server.ts +50 -74
- package/src/services/session/type.ts +4 -6
- package/src/services/share.ts +4 -4
- package/src/services/textToImage.ts +5 -2
- package/src/services/thread/client.ts +9 -15
- package/src/services/thread/server.ts +10 -15
- package/src/services/topic/client.ts +25 -25
- package/src/services/topic/server.ts +25 -42
- package/src/services/trace.ts +4 -4
- package/src/services/user/client.ts +13 -17
- package/src/services/user/server.ts +9 -13
- package/src/services/user/type.ts +1 -1
- package/src/store/chat/slices/message/reducer.ts +3 -2
- package/src/store/global/action.ts +27 -22
- package/src/store/global/initialState.ts +1 -0
- package/src/types/changelog.ts +6 -0
- package/src/types/message/index.ts +10 -8
- package/src/app/@modal/features/InterceptingContext.tsx +0 -9
- /package/src/components/{CircleLoading → Loading/CircleLoading}/index.tsx +0 -0
- /package/src/components/{FullscreenLoading → Loading/FullscreenLoading}/index.tsx +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Divider, Skeleton } from 'antd';
|
|
2
|
+
import { notFound } from 'next/navigation';
|
|
3
|
+
import { Fragment, Suspense } from 'react';
|
|
4
|
+
import { Flexbox } from 'react-layout-kit';
|
|
5
|
+
import urlJoin from 'url-join';
|
|
6
|
+
|
|
7
|
+
import Pagination from '@/app/@modal/(.)changelog/modal/features/Pagination';
|
|
8
|
+
import StructuredData from '@/components/StructuredData';
|
|
9
|
+
import { serverFeatureFlags } from '@/config/featureFlags';
|
|
10
|
+
import { BRANDING_NAME } from '@/const/branding';
|
|
11
|
+
import { OFFICIAL_SITE } from '@/const/url';
|
|
12
|
+
import { ldModule } from '@/server/ld';
|
|
13
|
+
import { metadataModule } from '@/server/metadata';
|
|
14
|
+
import { ChangelogService } from '@/server/services/changelog';
|
|
15
|
+
import { translation } from '@/server/translation';
|
|
16
|
+
import { isMobileDevice } from '@/utils/server/responsive';
|
|
17
|
+
|
|
18
|
+
import GridLayout from './features/GridLayout';
|
|
19
|
+
import Post from './features/Post';
|
|
20
|
+
|
|
21
|
+
export const generateMetadata = async () => {
|
|
22
|
+
const { t } = await translation('metadata');
|
|
23
|
+
return metadataModule.generate({
|
|
24
|
+
canonical: urlJoin(OFFICIAL_SITE, 'changelog'),
|
|
25
|
+
description: t('changelog.description', { appName: BRANDING_NAME }),
|
|
26
|
+
title: t('changelog.title'),
|
|
27
|
+
url: '/changelog',
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const Page = async () => {
|
|
32
|
+
const hideDocs = serverFeatureFlags().hideDocs;
|
|
33
|
+
|
|
34
|
+
if (hideDocs) return notFound();
|
|
35
|
+
|
|
36
|
+
const mobile = await isMobileDevice();
|
|
37
|
+
const { t, locale } = await translation('metadata');
|
|
38
|
+
const changelogService = new ChangelogService();
|
|
39
|
+
const data = await changelogService.getChangelogIndex();
|
|
40
|
+
|
|
41
|
+
const ld = ldModule.generate({
|
|
42
|
+
description: t('changelog.description', { appName: BRANDING_NAME }),
|
|
43
|
+
title: t('changelog.title', { appName: BRANDING_NAME }),
|
|
44
|
+
url: '/changelog',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
<StructuredData ld={ld} />
|
|
50
|
+
<Flexbox gap={mobile ? 16 : 48}>
|
|
51
|
+
{data.map((item) => (
|
|
52
|
+
<Fragment key={item.id}>
|
|
53
|
+
<Suspense
|
|
54
|
+
fallback={
|
|
55
|
+
<GridLayout>
|
|
56
|
+
<Divider />
|
|
57
|
+
<Skeleton active paragraph={{ rows: 5 }} />
|
|
58
|
+
</GridLayout>
|
|
59
|
+
}
|
|
60
|
+
>
|
|
61
|
+
<Post locale={locale} mobile={mobile} {...item} />
|
|
62
|
+
</Suspense>
|
|
63
|
+
</Fragment>
|
|
64
|
+
))}
|
|
65
|
+
</Flexbox>
|
|
66
|
+
<GridLayout>
|
|
67
|
+
<Pagination />
|
|
68
|
+
</GridLayout>
|
|
69
|
+
</>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default Page;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { Suspense, lazy } from 'react';
|
|
2
2
|
|
|
3
|
-
import Loading from '@/components/
|
|
3
|
+
import Loading from '@/components/Loading/BrandTextLoading';
|
|
4
4
|
import { isMobileDevice } from '@/utils/server/responsive';
|
|
5
5
|
|
|
6
6
|
import Desktop from './_layout/Desktop';
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import StructuredData from '@/components/StructuredData';
|
|
2
|
+
import { serverFeatureFlags } from '@/config/featureFlags';
|
|
2
3
|
import { BRANDING_NAME } from '@/const/branding';
|
|
4
|
+
import ChangelogModal from '@/features/ChangelogModal';
|
|
3
5
|
import { ldModule } from '@/server/ld';
|
|
4
6
|
import { metadataModule } from '@/server/metadata';
|
|
7
|
+
import { ChangelogService } from '@/server/services/changelog';
|
|
5
8
|
import { translation } from '@/server/translation';
|
|
6
9
|
import { isMobileDevice } from '@/utils/server/responsive';
|
|
7
10
|
|
|
@@ -11,17 +14,18 @@ import TelemetryNotification from './features/TelemetryNotification';
|
|
|
11
14
|
export const generateMetadata = async () => {
|
|
12
15
|
const { t } = await translation('metadata');
|
|
13
16
|
return metadataModule.generate({
|
|
14
|
-
description: t('chat.
|
|
17
|
+
description: t('chat.description', { appName: BRANDING_NAME }),
|
|
15
18
|
title: t('chat.title', { appName: BRANDING_NAME }),
|
|
16
19
|
url: '/chat',
|
|
17
20
|
});
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
const Page = async () => {
|
|
24
|
+
const hideDocs = serverFeatureFlags().hideDocs;
|
|
21
25
|
const mobile = await isMobileDevice();
|
|
22
26
|
const { t } = await translation('metadata');
|
|
23
27
|
const ld = ldModule.generate({
|
|
24
|
-
description: t('chat.
|
|
28
|
+
description: t('chat.description', { appName: BRANDING_NAME }),
|
|
25
29
|
title: t('chat.title', { appName: BRANDING_NAME }),
|
|
26
30
|
url: '/chat',
|
|
27
31
|
});
|
|
@@ -31,6 +35,9 @@ const Page = async () => {
|
|
|
31
35
|
<StructuredData ld={ld} />
|
|
32
36
|
<PageTitle />
|
|
33
37
|
<TelemetryNotification mobile={mobile} />
|
|
38
|
+
{!hideDocs && !mobile && (
|
|
39
|
+
<ChangelogModal currentId={await new ChangelogService().getLatestChangelogId()} />
|
|
40
|
+
)}
|
|
34
41
|
</>
|
|
35
42
|
);
|
|
36
43
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Suspense, lazy } from 'react';
|
|
2
2
|
|
|
3
|
+
import CircleLoading from '@/components/Loading/CircleLoading';
|
|
3
4
|
import ServerLayout from '@/components/server/ServerLayout';
|
|
4
5
|
|
|
5
6
|
import Desktop from './_layout/Desktop';
|
|
@@ -13,14 +14,14 @@ const Layout = ServerLayout({ Desktop, Mobile });
|
|
|
13
14
|
|
|
14
15
|
const Session = () => {
|
|
15
16
|
return (
|
|
16
|
-
|
|
17
|
+
<Suspense fallback={<CircleLoading />}>
|
|
17
18
|
<Layout>
|
|
18
19
|
<Suspense fallback={<SkeletonList />}>
|
|
19
20
|
<SessionListContent />
|
|
20
21
|
</Suspense>
|
|
21
22
|
</Layout>
|
|
22
23
|
<SessionHydration />
|
|
23
|
-
|
|
24
|
+
</Suspense>
|
|
24
25
|
);
|
|
25
26
|
};
|
|
26
27
|
|
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import CircleLoading from '@/components/Loading/BrandTextLoading';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import { Typography } from 'antd';
|
|
5
|
-
import { LoaderCircle } from 'lucide-react';
|
|
6
|
-
import { useTranslation } from 'react-i18next';
|
|
7
|
-
import { Center, Flexbox } from 'react-layout-kit';
|
|
8
|
-
|
|
9
|
-
export default () => {
|
|
10
|
-
const { t } = useTranslation('common');
|
|
11
|
-
return (
|
|
12
|
-
<Center height={'100%'} width={'100%'}>
|
|
13
|
-
<Flexbox align={'center'} gap={8}>
|
|
14
|
-
<div>
|
|
15
|
-
<Icon icon={LoaderCircle} size={'large'} spin />
|
|
16
|
-
</div>
|
|
17
|
-
<Typography.Text style={{ letterSpacing: '0.1em' }} type={'secondary'}>
|
|
18
|
-
{t('loading')}
|
|
19
|
-
</Typography.Text>
|
|
20
|
-
</Flexbox>
|
|
21
|
-
</Center>
|
|
22
|
-
);
|
|
23
|
-
};
|
|
3
|
+
export default () => <CircleLoading />;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Flexbox } from 'react-layout-kit';
|
|
2
2
|
|
|
3
|
-
import SkeletonLoading from '@/components/SkeletonLoading';
|
|
3
|
+
import SkeletonLoading from '@/components/Loading/SkeletonLoading';
|
|
4
4
|
import { isMobileDevice } from '@/utils/server/responsive';
|
|
5
5
|
|
|
6
6
|
const Loading = async () => {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
|
5
5
|
|
|
6
|
-
import CircleLoading from '@/components/
|
|
6
|
+
import CircleLoading from '@/components/Loading/BrandTextLoading';
|
|
7
7
|
import { useKnowledgeBaseStore } from '@/store/knowledgeBase';
|
|
8
8
|
|
|
9
9
|
import DatasetDetail from './DatasetDetail';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
4
|
|
|
5
|
-
import CircleLoading from '@/components/
|
|
5
|
+
import CircleLoading from '@/components/Loading/BrandTextLoading';
|
|
6
6
|
import { useKnowledgeBaseStore } from '@/store/knowledgeBase';
|
|
7
7
|
|
|
8
8
|
import EmptyGuide from './EmptyGuide';
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import { Suspense } from 'react';
|
|
2
|
+
|
|
3
|
+
import SkeletonLoading from '@/components/Loading/SkeletonLoading';
|
|
4
|
+
|
|
1
5
|
import UpgradeAlert from '../features/UpgradeAlert';
|
|
2
6
|
import CategoryContent from './features/CategoryContent';
|
|
3
7
|
|
|
4
8
|
const Category = () => {
|
|
5
9
|
return (
|
|
6
|
-
|
|
10
|
+
<Suspense fallback={<SkeletonLoading paragraph={{ rows: 7 }} title={false} />}>
|
|
7
11
|
<CategoryContent />
|
|
8
12
|
<UpgradeAlert />
|
|
9
|
-
|
|
13
|
+
</Suspense>
|
|
10
14
|
);
|
|
11
15
|
};
|
|
12
16
|
|
|
@@ -33,7 +33,7 @@ const SidebarLayout = ({ children, className, title, desc, ...rest }: SidebarLay
|
|
|
33
33
|
{...rest}
|
|
34
34
|
>
|
|
35
35
|
<PanelTitle desc={desc || t('header.desc')} title={title || t('header.title')} />
|
|
36
|
-
{children}
|
|
36
|
+
<Flexbox flex={1}>{children}</Flexbox>
|
|
37
37
|
<BrandWatermark paddingInline={12} />
|
|
38
38
|
</Flexbox>
|
|
39
39
|
);
|
|
@@ -7,7 +7,7 @@ import { Center, Flexbox } from 'react-layout-kit';
|
|
|
7
7
|
|
|
8
8
|
import { ProductLogo } from '@/components/Branding';
|
|
9
9
|
import { BRANDING_NAME } from '@/const/branding';
|
|
10
|
-
import { MANUAL_UPGRADE_URL, OFFICIAL_SITE
|
|
10
|
+
import { CHANGELOG_URL, MANUAL_UPGRADE_URL, OFFICIAL_SITE } from '@/const/url';
|
|
11
11
|
import { CURRENT_VERSION } from '@/const/version';
|
|
12
12
|
import { useNewVersion } from '@/features/User/UserPanel/useNewVersion';
|
|
13
13
|
import { useGlobalStore } from '@/store/global';
|
|
@@ -62,7 +62,7 @@ const Version = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
|
62
62
|
</Flexbox>
|
|
63
63
|
</Flexbox>
|
|
64
64
|
<Flexbox flex={mobile ? 1 : undefined} gap={8} horizontal>
|
|
65
|
-
<Link href={
|
|
65
|
+
<Link href={CHANGELOG_URL} style={{ flex: 1 }} target={'_blank'}>
|
|
66
66
|
<Button block={mobile}>{t('changelog')}</Button>
|
|
67
67
|
</Link>
|
|
68
68
|
{hasNewVersion && (
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import FullLoading from '@/components/Loading/BrandTextLoading';
|
|
2
2
|
|
|
3
|
-
export default () =>
|
|
4
|
-
return (
|
|
5
|
-
<div style={{ flex: 1 }}>
|
|
6
|
-
<SkeletonLoading paragraph={{ rows: 8 }} title={false} />
|
|
7
|
-
</div>
|
|
8
|
-
);
|
|
9
|
-
};
|
|
3
|
+
export default () => <FullLoading />;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createStyles } from 'antd-style';
|
|
4
|
+
import { PropsWithChildren, memo } from 'react';
|
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
|
6
|
+
|
|
7
|
+
const useStyles = createStyles(
|
|
8
|
+
({ css, token }) => css`
|
|
9
|
+
position: relative;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
background: ${token.colorFillSecondary};
|
|
12
|
+
|
|
13
|
+
&::before {
|
|
14
|
+
content: '';
|
|
15
|
+
|
|
16
|
+
position: absolute;
|
|
17
|
+
z-index: 1;
|
|
18
|
+
inset-block-start: 0;
|
|
19
|
+
inset-inline-start: 0;
|
|
20
|
+
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 1px;
|
|
23
|
+
|
|
24
|
+
background: ${token.colorFillTertiary};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&::after {
|
|
28
|
+
content: '';
|
|
29
|
+
|
|
30
|
+
position: absolute;
|
|
31
|
+
z-index: 1;
|
|
32
|
+
inset-block-end: 0;
|
|
33
|
+
inset-inline-start: 0;
|
|
34
|
+
|
|
35
|
+
width: 100%;
|
|
36
|
+
height: 1px;
|
|
37
|
+
|
|
38
|
+
background: ${token.colorFillTertiary};
|
|
39
|
+
}
|
|
40
|
+
`,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const Cover = memo<PropsWithChildren>(({ children }) => {
|
|
44
|
+
const { styles } = useStyles();
|
|
45
|
+
return <Flexbox className={styles}>{children}</Flexbox>;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export default Cover;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { FluentEmoji } from '@lobehub/ui';
|
|
4
|
+
import { createStyles } from 'antd-style';
|
|
5
|
+
import { memo } from 'react';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
|
+
import { Flexbox } from 'react-layout-kit';
|
|
8
|
+
|
|
9
|
+
const useStyles = createStyles(
|
|
10
|
+
({ css, token }) => css`
|
|
11
|
+
background: linear-gradient(to bottom, ${token.colorFillTertiary}, transparent);
|
|
12
|
+
`,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const Hero = memo(() => {
|
|
16
|
+
const { theme, styles } = useStyles();
|
|
17
|
+
const { t } = useTranslation('changelog');
|
|
18
|
+
return (
|
|
19
|
+
<Flexbox className={styles} gap={8} padding={24}>
|
|
20
|
+
<Flexbox align={'center'} gap={12} horizontal>
|
|
21
|
+
<h1 style={{ fontSize: 24, fontWeight: 'bold', margin: 0 }}>{t('welcomeBack')}</h1>
|
|
22
|
+
<FluentEmoji emoji={'🤯'} size={28} type={'anim'} />
|
|
23
|
+
</Flexbox>
|
|
24
|
+
<div style={{ color: theme.colorTextSecondary, fontSize: 16 }}>{t('addedWhileAway')}</div>
|
|
25
|
+
</Flexbox>
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export default Hero;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Icon } from '@lobehub/ui';
|
|
4
|
+
import { createStyles } from 'antd-style';
|
|
5
|
+
import { ChevronRightIcon } from 'lucide-react';
|
|
6
|
+
import Link from 'next/link';
|
|
7
|
+
import { memo } from 'react';
|
|
8
|
+
import { useTranslation } from 'react-i18next';
|
|
9
|
+
import { Flexbox } from 'react-layout-kit';
|
|
10
|
+
import urlJoin from 'url-join';
|
|
11
|
+
|
|
12
|
+
import { OFFICIAL_SITE } from '@/const/url';
|
|
13
|
+
|
|
14
|
+
const useStyles = createStyles(({ css, token }) => ({
|
|
15
|
+
button: css`
|
|
16
|
+
border: 1px solid ${token.colorBorderSecondary};
|
|
17
|
+
border-radius: ${token.borderRadiusLG}px;
|
|
18
|
+
|
|
19
|
+
&:hover {
|
|
20
|
+
background: ${token.colorFillTertiary};
|
|
21
|
+
}
|
|
22
|
+
`,
|
|
23
|
+
desc: css`
|
|
24
|
+
color: ${token.colorTextSecondary};
|
|
25
|
+
`,
|
|
26
|
+
title: css`
|
|
27
|
+
font-size: 16px;
|
|
28
|
+
font-weight: 500;
|
|
29
|
+
`,
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
const Pagination = memo(() => {
|
|
33
|
+
const { t } = useTranslation('changelog');
|
|
34
|
+
const { styles } = useStyles();
|
|
35
|
+
return (
|
|
36
|
+
<Flexbox gap={16} horizontal style={{ marginTop: 24 }} width={'100%'}>
|
|
37
|
+
<Link
|
|
38
|
+
href={urlJoin(OFFICIAL_SITE, '/changelog/page/2')}
|
|
39
|
+
style={{ color: 'inherit', flex: 1 }}
|
|
40
|
+
target={'_blank'}
|
|
41
|
+
>
|
|
42
|
+
<Flexbox align={'flex-end'} className={styles.button} gap={4} padding={16}>
|
|
43
|
+
<Flexbox align={'center'} className={styles.desc} gap={4} horizontal>
|
|
44
|
+
{t('pagination.prev')}
|
|
45
|
+
<Icon icon={ChevronRightIcon} />
|
|
46
|
+
</Flexbox>
|
|
47
|
+
<div className={styles.title}>{t('pagination.older')}</div>
|
|
48
|
+
</Flexbox>
|
|
49
|
+
</Link>
|
|
50
|
+
</Flexbox>
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export default Pagination;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Typography } from '@lobehub/ui';
|
|
2
|
+
import Link from 'next/link';
|
|
3
|
+
import { Flexbox } from 'react-layout-kit';
|
|
4
|
+
import urlJoin from 'url-join';
|
|
5
|
+
|
|
6
|
+
import { CustomMDX } from '@/components/mdx';
|
|
7
|
+
import Image from '@/components/mdx/Image';
|
|
8
|
+
import { OFFICIAL_SITE } from '@/const/url';
|
|
9
|
+
import { Locales } from '@/locales/resources';
|
|
10
|
+
import { ChangelogService } from '@/server/services/changelog';
|
|
11
|
+
import { ChangelogIndexItem } from '@/types/changelog';
|
|
12
|
+
|
|
13
|
+
import Cover from './Cover';
|
|
14
|
+
import PublishedTime from './PublishedTime';
|
|
15
|
+
import ReadDetail from './ReadDetail';
|
|
16
|
+
import VersionTag from './VersionTag';
|
|
17
|
+
|
|
18
|
+
const Post = async ({
|
|
19
|
+
id,
|
|
20
|
+
versionRange,
|
|
21
|
+
locale,
|
|
22
|
+
}: ChangelogIndexItem & { branch?: string; locale: Locales; mobile?: boolean }) => {
|
|
23
|
+
const changelogService = new ChangelogService();
|
|
24
|
+
const data = await changelogService.getPostById(id, { locale });
|
|
25
|
+
const url = urlJoin(OFFICIAL_SITE, 'changelog', id);
|
|
26
|
+
|
|
27
|
+
if (!data) return null;
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Flexbox gap={8}>
|
|
31
|
+
<Link href={url} style={{ color: 'inherit' }} target={'_blank'}>
|
|
32
|
+
<Cover>
|
|
33
|
+
<Image alt={data.title} src={data.image} />
|
|
34
|
+
</Cover>
|
|
35
|
+
</Link>
|
|
36
|
+
<Flexbox gap={8} paddingInline={24}>
|
|
37
|
+
<Typography headerMultiple={0.2} style={{ width: '100%' }}>
|
|
38
|
+
<Link href={url} style={{ color: 'inherit' }} target={'_blank'}>
|
|
39
|
+
<h1 id={id}>{data.rawTitle || data.title}</h1>
|
|
40
|
+
</Link>
|
|
41
|
+
<CustomMDX source={data.content} />
|
|
42
|
+
</Typography>
|
|
43
|
+
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'} width={'100%'}>
|
|
44
|
+
<VersionTag range={versionRange} />
|
|
45
|
+
<PublishedTime
|
|
46
|
+
date={data.date.toISOString()}
|
|
47
|
+
style={{ fontSize: 12, opacity: 0.5 }}
|
|
48
|
+
template={'MMMM D, YYYY'}
|
|
49
|
+
/>
|
|
50
|
+
</Flexbox>
|
|
51
|
+
<ReadDetail desc={data.description} postId={id} title={data.rawTitle || data.title} />
|
|
52
|
+
</Flexbox>
|
|
53
|
+
</Flexbox>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default Post;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createStyles } from 'antd-style';
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
|
+
import 'dayjs/locale/zh.js';
|
|
6
|
+
import { CSSProperties, FC } from 'react';
|
|
7
|
+
import { useTranslation } from 'react-i18next';
|
|
8
|
+
|
|
9
|
+
const useStyles = createStyles(({ css, token }) => {
|
|
10
|
+
return {
|
|
11
|
+
time: css`
|
|
12
|
+
margin-block: calc(var(--lobe-markdown-margin-multiple) * 1em);
|
|
13
|
+
|
|
14
|
+
font-size: 14px;
|
|
15
|
+
line-height: var(--lobe-markdown-line-height);
|
|
16
|
+
color: ${token.colorTextSecondary};
|
|
17
|
+
letter-spacing: 0.02em;
|
|
18
|
+
`,
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
interface PrivacyUpdatedProps {
|
|
23
|
+
className?: string;
|
|
24
|
+
date: string;
|
|
25
|
+
style?: CSSProperties;
|
|
26
|
+
template?: string;
|
|
27
|
+
}
|
|
28
|
+
const PublishedTime: FC<PrivacyUpdatedProps> = ({
|
|
29
|
+
date = new Date().toISOString(),
|
|
30
|
+
style,
|
|
31
|
+
className,
|
|
32
|
+
template = 'dddd, MMMM D YYYY',
|
|
33
|
+
}) => {
|
|
34
|
+
const { i18n } = useTranslation();
|
|
35
|
+
const { styles, cx } = useStyles();
|
|
36
|
+
const time = dayjs(date).locale(i18n.language).format(template);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<time
|
|
40
|
+
aria-label={'published-date'}
|
|
41
|
+
className={cx(styles.time, className)}
|
|
42
|
+
dateTime={time}
|
|
43
|
+
style={style}
|
|
44
|
+
>
|
|
45
|
+
{time}
|
|
46
|
+
</time>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default PublishedTime;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ActionIcon, Icon } from '@lobehub/ui';
|
|
4
|
+
import { Divider } from 'antd';
|
|
5
|
+
import { createStyles } from 'antd-style';
|
|
6
|
+
import { ChevronRightIcon } from 'lucide-react';
|
|
7
|
+
import Link from 'next/link';
|
|
8
|
+
import { memo } from 'react';
|
|
9
|
+
import { useTranslation } from 'react-i18next';
|
|
10
|
+
import { Flexbox } from 'react-layout-kit';
|
|
11
|
+
import urlJoin from 'url-join';
|
|
12
|
+
|
|
13
|
+
import { OFFICIAL_SITE } from '@/const/url';
|
|
14
|
+
import { useShare } from '@/hooks/useShare';
|
|
15
|
+
|
|
16
|
+
const useStyles = createStyles(
|
|
17
|
+
({ css, token }) => css`
|
|
18
|
+
position: relative;
|
|
19
|
+
|
|
20
|
+
margin-block: 16px 32px;
|
|
21
|
+
padding: 16px;
|
|
22
|
+
|
|
23
|
+
background: ${token.colorFillTertiary};
|
|
24
|
+
border-radius: ${token.borderRadiusLG}px;
|
|
25
|
+
`,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const ReadDetail = memo<{ desc: string; postId: string; title: string }>(
|
|
29
|
+
({ postId, title, desc }) => {
|
|
30
|
+
const { t } = useTranslation('changelog');
|
|
31
|
+
const { styles, theme } = useStyles();
|
|
32
|
+
const url = urlJoin(OFFICIAL_SITE, `/changelog/${postId}`);
|
|
33
|
+
const { x, telegram, reddit, mastodon, whatsapp } = useShare({ desc, title, url });
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Flexbox align={'center'} className={styles} gap={4} horizontal>
|
|
37
|
+
<Link href={x.link} style={{ color: 'inherit' }} target={'_blank'}>
|
|
38
|
+
<ActionIcon
|
|
39
|
+
fill={theme.colorTextSecondary}
|
|
40
|
+
icon={x.icon}
|
|
41
|
+
size={{ blockSize: 28, fontSize: 16 }}
|
|
42
|
+
/>
|
|
43
|
+
</Link>
|
|
44
|
+
<Link href={telegram.link} style={{ color: 'inherit' }} target={'_blank'}>
|
|
45
|
+
<ActionIcon
|
|
46
|
+
fill={theme.colorTextSecondary}
|
|
47
|
+
icon={telegram.icon}
|
|
48
|
+
size={{ blockSize: 28, fontSize: 16 }}
|
|
49
|
+
/>
|
|
50
|
+
</Link>
|
|
51
|
+
<Link href={reddit.link} style={{ color: 'inherit' }} target={'_blank'}>
|
|
52
|
+
<ActionIcon
|
|
53
|
+
fill={theme.colorTextSecondary}
|
|
54
|
+
icon={reddit.icon}
|
|
55
|
+
size={{ blockSize: 28, fontSize: 16 }}
|
|
56
|
+
/>
|
|
57
|
+
</Link>
|
|
58
|
+
<Link href={mastodon.link} style={{ color: 'inherit' }} target={'_blank'}>
|
|
59
|
+
<ActionIcon
|
|
60
|
+
fill={theme.colorTextSecondary}
|
|
61
|
+
icon={mastodon.icon}
|
|
62
|
+
size={{ blockSize: 28, fontSize: 16 }}
|
|
63
|
+
/>
|
|
64
|
+
</Link>
|
|
65
|
+
<Link href={whatsapp.link} style={{ color: 'inherit' }} target={'_blank'}>
|
|
66
|
+
<ActionIcon
|
|
67
|
+
fill={theme.colorTextSecondary}
|
|
68
|
+
icon={whatsapp.icon}
|
|
69
|
+
size={{ blockSize: 28, fontSize: 16 }}
|
|
70
|
+
/>
|
|
71
|
+
</Link>
|
|
72
|
+
<Divider style={{ height: '100%' }} type={'vertical'} />
|
|
73
|
+
<Link href={url} style={{ color: 'inherit', flex: 1 }} target={'_blank'}>
|
|
74
|
+
<Flexbox
|
|
75
|
+
align={'center'}
|
|
76
|
+
horizontal
|
|
77
|
+
justify={'space-between'}
|
|
78
|
+
paddingInline={4}
|
|
79
|
+
width={'100%'}
|
|
80
|
+
>
|
|
81
|
+
{t('readDetails')}
|
|
82
|
+
<Icon
|
|
83
|
+
color={theme.colorTextSecondary}
|
|
84
|
+
icon={ChevronRightIcon}
|
|
85
|
+
size={{ fontSize: 20 }}
|
|
86
|
+
/>
|
|
87
|
+
</Flexbox>
|
|
88
|
+
</Link>
|
|
89
|
+
</Flexbox>
|
|
90
|
+
);
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
export default ReadDetail;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo, useEffect } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useGlobalStore } from '@/store/global';
|
|
6
|
+
|
|
7
|
+
const UpdateChangelogStatus = memo<{ currentId?: string }>(({ currentId }) => {
|
|
8
|
+
const [latestChangelogId, updateSystemStatus] = useGlobalStore((s) => [
|
|
9
|
+
s.status.latestChangelogId,
|
|
10
|
+
s.updateSystemStatus,
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (!currentId || currentId === latestChangelogId) return;
|
|
15
|
+
updateSystemStatus({ latestChangelogId: currentId });
|
|
16
|
+
}, [latestChangelogId, currentId]);
|
|
17
|
+
|
|
18
|
+
return null;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export default UpdateChangelogStatus;
|