@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;
|