@4399ywkf/cli 1.0.7 → 1.0.9
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/dist/templates/AntdStaticMethods/index.tsx +20 -0
- package/dist/templates/AppTheme.tsx +136 -0
- package/dist/templates/DIRECTORY_STRUCTURE.md +141 -0
- package/dist/templates/GlobalProvider/AppTheme.tsx +136 -0
- package/dist/templates/GlobalProvider/Locale.tsx +84 -0
- package/dist/templates/GlobalProvider/Query.tsx +12 -0
- package/dist/templates/GlobalProvider/StyleRegistry.tsx +9 -0
- package/dist/templates/GlobalProvider/index.tsx +23 -0
- package/dist/templates/HarmonyOS_Sans_Bold.woff2 +0 -0
- package/dist/templates/HarmonyOS_Sans_Medium.woff2 +0 -0
- package/dist/templates/HarmonyOS_Sans_Regular.woff2 +0 -0
- package/dist/templates/Locale.tsx +49 -54
- package/dist/templates/MainContentWrap.tsx +11 -15
- package/dist/templates/Query.tsx +12 -0
- package/dist/templates/StyleRegistry.tsx +9 -0
- package/dist/templates/ThemeContext.tsx +27 -24
- package/dist/templates/analyzeUnusedKeys.ts +506 -0
- package/dist/templates/app/.i18nrc.js +57 -0
- package/dist/templates/app/config/env/.env.public.tpl +2 -19
- package/dist/templates/app/config/jwt/index.ts +4 -4
- package/dist/templates/app/config/request/error-handler.ts +67 -0
- package/dist/templates/app/config/request/index.ts +127 -129
- package/dist/templates/app/config/request/interceptors.ts +118 -0
- package/dist/templates/app/config/request/token-manager.ts +23 -0
- package/dist/templates/app/config/request/types.ts +63 -0
- package/dist/templates/app/config/rspack/rspack.config.mjs +62 -61
- package/dist/templates/app/config/rspack/rspack.prod.mjs +41 -62
- package/dist/templates/app/docs/DIRECTORY_STRUCTURE.md +141 -0
- package/dist/templates/app/docs/glossary.md +11 -0
- package/dist/templates/app/locales/zh-CN/common.json +3 -0
- package/dist/templates/app/package.json.tpl +8 -25
- package/dist/templates/app/public/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
- package/dist/templates/app/public/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
- package/dist/templates/app/public/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
- package/dist/templates/app/react-app-env.d.ts +13 -8
- package/dist/templates/app/scripts/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
- package/dist/templates/app/scripts/i18nWorkflow/cleanUnusedKeys.ts +344 -0
- package/dist/templates/app/scripts/i18nWorkflow/const.ts +18 -0
- package/dist/templates/app/scripts/i18nWorkflow/flattenLocaleKeys.ts +139 -0
- package/dist/templates/app/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
- package/dist/templates/app/scripts/i18nWorkflow/genDiff.ts +49 -0
- package/dist/templates/app/scripts/i18nWorkflow/i18nConfig.ts +7 -0
- package/dist/templates/app/scripts/i18nWorkflow/index.ts +11 -0
- package/dist/templates/app/scripts/i18nWorkflow/protectedPatterns.ts +91 -0
- package/dist/templates/app/scripts/i18nWorkflow/utils.ts +76 -0
- package/dist/templates/app/src/bootstrap/index.ts +34 -0
- package/dist/templates/app/src/components/AntdStaticMethods/index.tsx +20 -0
- package/dist/templates/app/src/config/env.ts +84 -0
- package/dist/templates/app/src/index.tsx +13 -51
- package/dist/templates/app/src/layout/GlobalProvider/AppTheme.tsx +136 -0
- package/dist/templates/app/src/layout/GlobalProvider/Locale.tsx +84 -0
- package/dist/templates/app/src/layout/GlobalProvider/Query.tsx +12 -0
- package/dist/templates/app/src/layout/GlobalProvider/StyleRegistry.tsx +9 -0
- package/dist/templates/app/src/layout/GlobalProvider/index.tsx +23 -0
- package/dist/templates/app/src/layout/Locale.tsx +14 -18
- package/dist/templates/app/src/layout/MainContentWrap.tsx +11 -15
- package/dist/templates/app/src/layout/ThemeContext.tsx +27 -24
- package/dist/templates/app/src/locales/default/common.ts +3 -1
- package/dist/templates/app/src/locales/utils.ts +23 -0
- package/dist/templates/app/src/micro/garfish.ts +53 -0
- package/dist/templates/app/src/pages/base/index.tsx +280 -25
- package/dist/templates/app/src/routes.tsx +21 -12
- package/dist/templates/app/src/types/global.d.ts +19 -0
- package/dist/templates/app/src/utils/index.ts +3 -1
- package/dist/templates/app/store/middleware/createDevtools.ts +7 -7
- package/dist/templates/app/tsconfig.json +19 -3
- package/dist/templates/base/index.tsx +280 -25
- package/dist/templates/bootstrap/index.ts +34 -0
- package/dist/templates/cleanUnusedKeys.ts +344 -0
- package/dist/templates/common.json +3 -0
- package/dist/templates/common.ts +3 -1
- package/dist/templates/components/AntdStaticMethods/index.tsx +20 -0
- package/dist/templates/config/env/.env.public.tpl +2 -19
- package/dist/templates/config/env.ts +84 -0
- package/dist/templates/config/jwt/index.ts +4 -4
- package/dist/templates/config/request/error-handler.ts +67 -0
- package/dist/templates/config/request/index.ts +127 -129
- package/dist/templates/config/request/interceptors.ts +118 -0
- package/dist/templates/config/request/token-manager.ts +23 -0
- package/dist/templates/config/request/types.ts +63 -0
- package/dist/templates/config/rspack/rspack.config.mjs +62 -61
- package/dist/templates/config/rspack/rspack.prod.mjs +41 -62
- package/dist/templates/const.ts +18 -0
- package/dist/templates/createDevtools.ts +7 -7
- package/dist/templates/default/common.ts +3 -1
- package/dist/templates/docs/DIRECTORY_STRUCTURE.md +141 -0
- package/dist/templates/docs/glossary.md +11 -0
- package/dist/templates/env/.env.public.tpl +2 -19
- package/dist/templates/env.ts +83 -2
- package/dist/templates/error-handler.ts +67 -0
- package/dist/templates/flattenLocaleKeys.ts +139 -0
- package/dist/templates/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
- package/dist/templates/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
- package/dist/templates/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
- package/dist/templates/garfish.ts +53 -0
- package/dist/templates/genDefaultLocale.ts +19 -0
- package/dist/templates/genDiff.ts +49 -0
- package/dist/templates/global.d.ts +19 -0
- package/dist/templates/glossary.md +11 -0
- package/dist/templates/i18nConfig.ts +7 -0
- package/dist/templates/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
- package/dist/templates/i18nWorkflow/cleanUnusedKeys.ts +344 -0
- package/dist/templates/i18nWorkflow/const.ts +18 -0
- package/dist/templates/i18nWorkflow/flattenLocaleKeys.ts +139 -0
- package/dist/templates/i18nWorkflow/genDefaultLocale.ts +19 -0
- package/dist/templates/i18nWorkflow/genDiff.ts +49 -0
- package/dist/templates/i18nWorkflow/i18nConfig.ts +7 -0
- package/dist/templates/i18nWorkflow/index.ts +11 -0
- package/dist/templates/i18nWorkflow/protectedPatterns.ts +91 -0
- package/dist/templates/i18nWorkflow/utils.ts +76 -0
- package/dist/templates/index.tsx +280 -25
- package/dist/templates/interceptors.ts +118 -0
- package/dist/templates/jwt/index.ts +4 -4
- package/dist/templates/layout/GlobalProvider/AppTheme.tsx +136 -0
- package/dist/templates/layout/GlobalProvider/Locale.tsx +84 -0
- package/dist/templates/layout/GlobalProvider/Query.tsx +12 -0
- package/dist/templates/layout/GlobalProvider/StyleRegistry.tsx +9 -0
- package/dist/templates/layout/GlobalProvider/index.tsx +23 -0
- package/dist/templates/layout/Locale.tsx +14 -18
- package/dist/templates/layout/MainContentWrap.tsx +11 -15
- package/dist/templates/layout/ThemeContext.tsx +27 -24
- package/dist/templates/locales/default/common.ts +3 -1
- package/dist/templates/locales/utils.ts +23 -0
- package/dist/templates/locales/zh-CN/common.json +3 -0
- package/dist/templates/micro/garfish.ts +53 -0
- package/dist/templates/middleware/createDevtools.ts +7 -7
- package/dist/templates/package.json.tpl +8 -25
- package/dist/templates/page.tsx +21 -19
- package/dist/templates/pages/base/index.tsx +280 -25
- package/dist/templates/protectedPatterns.ts +91 -0
- package/dist/templates/public/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
- package/dist/templates/public/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
- package/dist/templates/public/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
- package/dist/templates/react-app-env.d.ts +13 -8
- package/dist/templates/request/error-handler.ts +67 -0
- package/dist/templates/request/index.ts +127 -129
- package/dist/templates/request/interceptors.ts +118 -0
- package/dist/templates/request/token-manager.ts +23 -0
- package/dist/templates/request/types.ts +63 -0
- package/dist/templates/routes.tsx +21 -12
- package/dist/templates/rspack/rspack.config.mjs +62 -61
- package/dist/templates/rspack/rspack.prod.mjs +41 -62
- package/dist/templates/rspack.config.mjs +62 -61
- package/dist/templates/rspack.prod.mjs +41 -62
- package/dist/templates/scripts/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
- package/dist/templates/scripts/i18nWorkflow/cleanUnusedKeys.ts +344 -0
- package/dist/templates/scripts/i18nWorkflow/const.ts +18 -0
- package/dist/templates/scripts/i18nWorkflow/flattenLocaleKeys.ts +139 -0
- package/dist/templates/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
- package/dist/templates/scripts/i18nWorkflow/genDiff.ts +49 -0
- package/dist/templates/scripts/i18nWorkflow/i18nConfig.ts +7 -0
- package/dist/templates/scripts/i18nWorkflow/index.ts +11 -0
- package/dist/templates/scripts/i18nWorkflow/protectedPatterns.ts +91 -0
- package/dist/templates/scripts/i18nWorkflow/utils.ts +76 -0
- package/dist/templates/src/bootstrap/index.ts +34 -0
- package/dist/templates/src/components/AntdStaticMethods/index.tsx +20 -0
- package/dist/templates/src/config/env.ts +84 -0
- package/dist/templates/src/index.tsx +13 -51
- package/dist/templates/src/layout/GlobalProvider/AppTheme.tsx +136 -0
- package/dist/templates/src/layout/GlobalProvider/Locale.tsx +84 -0
- package/dist/templates/src/layout/GlobalProvider/Query.tsx +12 -0
- package/dist/templates/src/layout/GlobalProvider/StyleRegistry.tsx +9 -0
- package/dist/templates/src/layout/GlobalProvider/index.tsx +23 -0
- package/dist/templates/src/layout/Locale.tsx +14 -18
- package/dist/templates/src/layout/MainContentWrap.tsx +11 -15
- package/dist/templates/src/layout/ThemeContext.tsx +27 -24
- package/dist/templates/src/locales/default/common.ts +3 -1
- package/dist/templates/src/locales/utils.ts +23 -0
- package/dist/templates/src/micro/garfish.ts +53 -0
- package/dist/templates/src/pages/base/index.tsx +280 -25
- package/dist/templates/src/routes.tsx +21 -12
- package/dist/templates/src/types/global.d.ts +19 -0
- package/dist/templates/src/utils/index.ts +3 -1
- package/dist/templates/store/middleware/createDevtools.ts +7 -7
- package/dist/templates/token-manager.ts +23 -0
- package/dist/templates/tsconfig.json +19 -3
- package/dist/templates/type.ts +23 -24
- package/dist/templates/types/global.d.ts +19 -0
- package/dist/templates/utils/index.ts +3 -1
- package/dist/templates/utils.ts +23 -0
- package/dist/templates/zh-CN/common.json +3 -0
- package/package.json +19 -21
- package/dist/templates/app/config/sentry/sentry.config.ts +0 -188
- package/dist/templates/app/src/hooks/useRouteTitle.tsx +0 -36
- package/dist/templates/app/src/hooks/useSentry.ts +0 -92
- package/dist/templates/app/src/pages/base/layout.tsx +0 -6
- package/dist/templates/app/src/pages/base/page.tsx +0 -25
- package/dist/templates/app/src/utils/env.ts +0 -3
- package/dist/templates/app/src/utils/format.ts +0 -21
- package/dist/templates/app/src/utils/getMicroApp.ts +0 -39
- package/dist/templates/app/src/utils/sentry.ts +0 -187
- package/dist/templates/app/src/utils/sentryDecorators.ts +0 -34
- package/dist/templates/app/src/utils/updateVersion.ts +0 -186
- package/dist/templates/base/layout.tsx +0 -6
- package/dist/templates/base/page.tsx +0 -25
- package/dist/templates/config/public/404.png +0 -0
- package/dist/templates/config/public/favicon.ico +0 -0
- package/dist/templates/config/public/images/banner_market_modal.webp +0 -0
- package/dist/templates/config/public/images/chatmode_chat_dark.webp +0 -0
- package/dist/templates/config/public/images/chatmode_chat_light.webp +0 -0
- package/dist/templates/config/public/images/chatmode_docs_dark.webp +0 -0
- package/dist/templates/config/public/images/chatmode_docs_light.webp +0 -0
- package/dist/templates/config/public/images/empty_topic_dark.webp +0 -0
- package/dist/templates/config/public/images/empty_topic_light.webp +0 -0
- package/dist/templates/config/public/images/screenshot_background.webp +0 -0
- package/dist/templates/config/public/images/theme_auto.webp +0 -0
- package/dist/templates/config/public/images/theme_dark.webp +0 -0
- package/dist/templates/config/public/images/theme_light.webp +0 -0
- package/dist/templates/config/public/index.html +0 -29
- package/dist/templates/config/sentry/sentry.config.ts +0 -188
- package/dist/templates/format.ts +0 -21
- package/dist/templates/getMicroApp.ts +0 -39
- package/dist/templates/hooks/useRouteTitle.tsx +0 -36
- package/dist/templates/hooks/useSentry.ts +0 -92
- package/dist/templates/layout.tsx +0 -6
- package/dist/templates/pages/base/layout.tsx +0 -6
- package/dist/templates/pages/base/page.tsx +0 -25
- package/dist/templates/sentry/sentry.config.ts +0 -188
- package/dist/templates/sentry.config.ts +0 -188
- package/dist/templates/sentry.ts +0 -187
- package/dist/templates/sentryDecorators.ts +0 -34
- package/dist/templates/src/hooks/useRouteTitle.tsx +0 -36
- package/dist/templates/src/hooks/useSentry.ts +0 -92
- package/dist/templates/src/pages/base/layout.tsx +0 -6
- package/dist/templates/src/pages/base/page.tsx +0 -25
- package/dist/templates/src/utils/env.ts +0 -3
- package/dist/templates/src/utils/format.ts +0 -21
- package/dist/templates/src/utils/getMicroApp.ts +0 -39
- package/dist/templates/src/utils/sentry.ts +0 -187
- package/dist/templates/src/utils/sentryDecorators.ts +0 -34
- package/dist/templates/src/utils/updateVersion.ts +0 -186
- package/dist/templates/updateVersion.ts +0 -186
- package/dist/templates/useRouteTitle.tsx +0 -36
- package/dist/templates/useSentry.ts +0 -92
- package/dist/templates/utils/env.ts +0 -3
- package/dist/templates/utils/format.ts +0 -21
- package/dist/templates/utils/getMicroApp.ts +0 -39
- package/dist/templates/utils/sentry.ts +0 -187
- package/dist/templates/utils/sentryDecorators.ts +0 -34
- package/dist/templates/utils/updateVersion.ts +0 -186
- /package/dist/templates/app/{config/public → public}/404.png +0 -0
- /package/dist/templates/app/{config/public → public}/favicon.ico +0 -0
- /package/dist/templates/app/{config/public → public}/images/banner_market_modal.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/chatmode_chat_dark.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/chatmode_chat_light.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/chatmode_docs_dark.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/chatmode_docs_light.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/empty_topic_dark.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/empty_topic_light.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/screenshot_background.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/theme_auto.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/theme_dark.webp +0 -0
- /package/dist/templates/app/{config/public → public}/images/theme_light.webp +0 -0
- /package/dist/templates/app/{config/public → public}/index.html +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ConfigProvider } from 'antd';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import { type PropsWithChildren, memo, useEffect, useState } from 'react';
|
|
4
|
+
import { isRtlLang } from 'rtl-detect';
|
|
5
|
+
|
|
6
|
+
import { createI18nNext } from '@/locales/create';
|
|
7
|
+
import { getAntdLocale } from '@/utils/locale';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const updateDayjs = async (lang: string) => {
|
|
11
|
+
let dayJSLocale;
|
|
12
|
+
try {
|
|
13
|
+
// dayjs locale is using `en` instead of `en-US`
|
|
14
|
+
// refs: https://github.com/lobehub/lobe-chat/issues/3396
|
|
15
|
+
const locale = lang!.toLowerCase() === 'en-us' ? 'en' : lang!.toLowerCase();
|
|
16
|
+
|
|
17
|
+
dayJSLocale = await import(`dayjs/locale/${locale}.js`);
|
|
18
|
+
} catch {
|
|
19
|
+
console.warn(`dayjs locale for ${lang} not found, fallback to en`);
|
|
20
|
+
dayJSLocale = await import(`dayjs/locale/en.js`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
dayjs.locale(dayJSLocale.default);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
interface LocaleLayoutProps extends PropsWithChildren {
|
|
27
|
+
antdLocale?: any;
|
|
28
|
+
defaultLang?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const Locale = memo<LocaleLayoutProps>(({ children, defaultLang, antdLocale }) => {
|
|
32
|
+
const [i18n] = useState(() => createI18nNext(defaultLang));
|
|
33
|
+
const [lang, setLang] = useState(defaultLang);
|
|
34
|
+
const [locale, setLocale] = useState(antdLocale);
|
|
35
|
+
|
|
36
|
+
if (!i18n.instance.isInitialized)
|
|
37
|
+
i18n.init().then(async () => {
|
|
38
|
+
if (!lang) return;
|
|
39
|
+
|
|
40
|
+
await updateDayjs(lang);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// handle i18n instance language change
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const handleLang = async (lng: string) => {
|
|
46
|
+
setLang(lng);
|
|
47
|
+
|
|
48
|
+
if (lang === lng) return;
|
|
49
|
+
|
|
50
|
+
const newLocale = await getAntdLocale(lng);
|
|
51
|
+
setLocale(newLocale);
|
|
52
|
+
|
|
53
|
+
await updateDayjs(lng);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
i18n.instance.on('languageChanged', handleLang);
|
|
57
|
+
return () => {
|
|
58
|
+
i18n.instance.off('languageChanged', handleLang);
|
|
59
|
+
};
|
|
60
|
+
}, [i18n, lang]);
|
|
61
|
+
|
|
62
|
+
// detect document direction
|
|
63
|
+
const documentDir = isRtlLang(lang!) ? 'rtl' : 'ltr';
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<ConfigProvider
|
|
67
|
+
direction={documentDir}
|
|
68
|
+
locale={locale}
|
|
69
|
+
theme={{
|
|
70
|
+
components: {
|
|
71
|
+
Button: {
|
|
72
|
+
contentFontSizeSM: 12,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
{children}
|
|
78
|
+
</ConfigProvider>
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
Locale.displayName = 'Locale';
|
|
83
|
+
|
|
84
|
+
export default Locale;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
2
|
+
import React, { type PropsWithChildren, useEffect, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
const QueryProvider = ({ children }: PropsWithChildren) => {
|
|
5
|
+
const [queryClient] = useState(() => new QueryClient());
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
9
|
+
);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default QueryProvider;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import StyleRegistry from "./StyleRegistry";
|
|
2
|
+
import AppTheme from "./AppTheme";
|
|
3
|
+
import QueryProvider from "./Query";
|
|
4
|
+
import Locale from "./Locale";
|
|
5
|
+
import { Outlet } from "react-router";
|
|
6
|
+
|
|
7
|
+
interface GlobalProviderProps {
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function GlobalProvider({ }: GlobalProviderProps) {
|
|
12
|
+
return (
|
|
13
|
+
<StyleRegistry>
|
|
14
|
+
<Locale>
|
|
15
|
+
<AppTheme>
|
|
16
|
+
<QueryProvider>
|
|
17
|
+
<Outlet />
|
|
18
|
+
</QueryProvider>
|
|
19
|
+
</AppTheme>
|
|
20
|
+
</Locale>
|
|
21
|
+
</StyleRegistry>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { ConfigProvider } from
|
|
2
|
-
import type { Locale as AntdLocale } from
|
|
3
|
-
import dayjs from
|
|
1
|
+
import { ConfigProvider } from "antd";
|
|
2
|
+
import type { Locale as AntdLocale } from "antd/es/locale";
|
|
3
|
+
import dayjs from "dayjs";
|
|
4
4
|
import React, {
|
|
5
5
|
type PropsWithChildren,
|
|
6
6
|
memo,
|
|
7
7
|
useEffect,
|
|
8
8
|
useState,
|
|
9
|
-
} from
|
|
9
|
+
} from "react";
|
|
10
10
|
|
|
11
|
-
import { isRtlLang } from
|
|
11
|
+
import { isRtlLang } from "rtl-detect";
|
|
12
12
|
|
|
13
|
-
import { createI18nNext } from
|
|
14
|
-
import { getAntdLocale } from
|
|
13
|
+
import { createI18nNext } from "@/locales/create";
|
|
14
|
+
import { getAntdLocale } from "@/utils/locale";
|
|
15
15
|
|
|
16
16
|
const updateDayjs = async (lang: string) => {
|
|
17
17
|
// load default lang
|
|
@@ -19,12 +19,12 @@ const updateDayjs = async (lang: string) => {
|
|
|
19
19
|
try {
|
|
20
20
|
// dayjs locale is using `en` instead of `en-US`
|
|
21
21
|
// refs: https://github.com/lobehub/lobe-chat/issues/3396
|
|
22
|
-
const locale = lang.toLowerCase() ===
|
|
22
|
+
const locale = lang.toLowerCase() === "en-us" ? "en" : lang.toLowerCase();
|
|
23
23
|
|
|
24
24
|
dayJSLocale = await import(`dayjs/locale/${locale}.js`);
|
|
25
25
|
} catch {
|
|
26
26
|
console.warn(`dayjs locale for ${lang} not found, fallback to en`);
|
|
27
|
-
dayJSLocale = await import(
|
|
27
|
+
dayJSLocale = await import("dayjs/locale/en.js");
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
dayjs.locale(dayJSLocale.default);
|
|
@@ -41,8 +41,6 @@ const Locale = memo<LocaleLayoutProps>(
|
|
|
41
41
|
const [lang, setLang] = useState(defaultLang);
|
|
42
42
|
const [locale, setLocale] = useState(antdLocale);
|
|
43
43
|
|
|
44
|
-
console.log(antdLocale, defaultLang);
|
|
45
|
-
|
|
46
44
|
// if on browser side, init i18n instance only once
|
|
47
45
|
if (!i18n.instance.isInitialized)
|
|
48
46
|
// console.debug('locale', lang);
|
|
@@ -65,25 +63,23 @@ const Locale = memo<LocaleLayoutProps>(
|
|
|
65
63
|
await updateDayjs(lng);
|
|
66
64
|
};
|
|
67
65
|
|
|
68
|
-
i18n.instance.on(
|
|
66
|
+
i18n.instance.on("languageChanged", handleLang);
|
|
69
67
|
return () => {
|
|
70
|
-
i18n.instance.off(
|
|
68
|
+
i18n.instance.off("languageChanged", handleLang);
|
|
71
69
|
};
|
|
72
70
|
}, [i18n, lang]);
|
|
73
71
|
|
|
74
72
|
// detect document direction
|
|
75
|
-
const documentDir = isRtlLang(lang) ?
|
|
76
|
-
|
|
77
|
-
console.log(documentDir, locale);
|
|
73
|
+
const documentDir = isRtlLang(lang) ? "rtl" : "ltr";
|
|
78
74
|
|
|
79
75
|
return (
|
|
80
76
|
<ConfigProvider direction={documentDir} locale={locale as AntdLocale}>
|
|
81
77
|
{children}
|
|
82
78
|
</ConfigProvider>
|
|
83
79
|
);
|
|
84
|
-
}
|
|
80
|
+
}
|
|
85
81
|
);
|
|
86
82
|
|
|
87
|
-
Locale.displayName =
|
|
83
|
+
Locale.displayName = "Locale";
|
|
88
84
|
|
|
89
85
|
export default Locale;
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Locale as AntdLocale } from 'antd/es/locale';
|
|
3
|
-
import React, { useState, useEffect } from 'react';
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
4
2
|
|
|
5
|
-
import { QueryClient, QueryClientProvider } from
|
|
6
|
-
import { Outlet } from
|
|
7
|
-
import
|
|
8
|
-
import { DEFAULT_LANG } from
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import AppTheme from './ThemeContext';
|
|
3
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
|
+
import { Outlet } from "react-router";
|
|
5
|
+
import "../index.css";
|
|
6
|
+
import { DEFAULT_LANG } from "@/const/locale";
|
|
7
|
+
import { getAntdLocale } from "@/utils";
|
|
8
|
+
import queryString from "query-string";
|
|
9
|
+
import Locale from "./Locale";
|
|
10
|
+
import AppTheme from "./ThemeContext";
|
|
14
11
|
|
|
15
12
|
export const MainContentWrap = () => {
|
|
16
|
-
useRouteTitle();
|
|
17
13
|
const [antdLocale, setAntdLocale] = useState<unknown>(null);
|
|
18
14
|
const [isLocaleLoaded, setIsLocaleLoaded] = useState(false);
|
|
19
15
|
|
|
@@ -32,11 +28,11 @@ export const MainContentWrap = () => {
|
|
|
32
28
|
const loadLocale = async () => {
|
|
33
29
|
try {
|
|
34
30
|
const loadedLocale = await getAntdLocale(
|
|
35
|
-
(lang as string) ?? DEFAULT_LANG
|
|
31
|
+
(lang as string) ?? DEFAULT_LANG
|
|
36
32
|
);
|
|
37
33
|
setAntdLocale(loadedLocale);
|
|
38
34
|
} catch (error) {
|
|
39
|
-
console.error(
|
|
35
|
+
console.error("Failed to load locale:", error);
|
|
40
36
|
// 保持默认的中文 locale
|
|
41
37
|
} finally {
|
|
42
38
|
setIsLocaleLoaded(true);
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import ThemeProvider from
|
|
2
|
-
import { CLOUD_THEME_APPEARANCE } from
|
|
3
|
-
import { setCookie } from
|
|
1
|
+
import ThemeProvider from "@/components/ThemeProvider";
|
|
2
|
+
import { CLOUD_THEME_APPEARANCE } from "@/const/theme";
|
|
3
|
+
import { setCookie } from "@/utils/cookie";
|
|
4
4
|
|
|
5
5
|
// import { useGlobalStore } from "@store/global";
|
|
6
|
-
import React, { memo, useEffect, type ReactNode } from
|
|
6
|
+
import React, { memo, useEffect, type ReactNode } from "react";
|
|
7
|
+
|
|
8
|
+
import { SYSTEM_PREFIX } from "@/const/system";
|
|
9
|
+
import { GlobalStyle } from "@/styles";
|
|
10
|
+
import { useUserStore } from "@store/user";
|
|
11
|
+
import { createStyles } from "antd-style";
|
|
12
|
+
import HarmonyOS_Sans_Regular from "@public/fonts/HarmonyOS_Sans_Regular.woff2";
|
|
7
13
|
|
|
8
|
-
import { SYSTEM_PREFIX } from '@/const/system';
|
|
9
|
-
import { GlobalStyle } from '@/styles';
|
|
10
|
-
import { useUserStore } from '@store/user';
|
|
11
|
-
import { createStyles } from 'antd-style';
|
|
12
14
|
const useStyles = createStyles(({ css, token }) => ({
|
|
13
15
|
app: css`
|
|
14
16
|
position: relative;
|
|
@@ -70,55 +72,56 @@ interface AppThemeProps {
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
const AppTheme = memo(({ children }: AppThemeProps) => {
|
|
73
|
-
const themeMode = useUserStore(s => s.themeMode);
|
|
74
|
-
const animationMode = useUserStore(s => s.animationMode);
|
|
75
|
-
const neutralColor = useUserStore(s => s.neutralColor);
|
|
76
|
-
const primaryColor = useUserStore(s => s.primaryColor);
|
|
75
|
+
const themeMode = useUserStore((s) => s.themeMode);
|
|
76
|
+
const animationMode = useUserStore((s) => s.animationMode);
|
|
77
|
+
const neutralColor = useUserStore((s) => s.neutralColor);
|
|
78
|
+
const primaryColor = useUserStore((s) => s.primaryColor);
|
|
77
79
|
const { styles, cx } = useStyles();
|
|
78
80
|
|
|
79
81
|
useEffect(() => {
|
|
80
82
|
// Update data-theme accordingly if user selects light or dark
|
|
81
|
-
if (themeMode !==
|
|
83
|
+
if (themeMode !== "auto") {
|
|
82
84
|
document.documentElement.dataset.theme = themeMode;
|
|
83
85
|
return;
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
// For auto mode, we need to watch system preferences
|
|
87
|
-
const mediaQuery = window.matchMedia(
|
|
89
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
88
90
|
|
|
89
91
|
// Set initial theme based on system preference
|
|
90
92
|
document.documentElement.dataset.theme = mediaQuery.matches
|
|
91
|
-
?
|
|
92
|
-
:
|
|
93
|
+
? "dark"
|
|
94
|
+
: "light";
|
|
93
95
|
|
|
94
96
|
// Update theme when system preference changes
|
|
95
97
|
function handleChange(e) {
|
|
96
|
-
document.documentElement.dataset.theme = e.matches ?
|
|
98
|
+
document.documentElement.dataset.theme = e.matches ? "dark" : "light";
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
mediaQuery.addEventListener(
|
|
100
|
-
return () => mediaQuery.removeEventListener(
|
|
101
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
102
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
101
103
|
}, [themeMode]);
|
|
102
104
|
|
|
103
105
|
return (
|
|
104
106
|
<ThemeProvider
|
|
105
107
|
prefixCls={SYSTEM_PREFIX}
|
|
106
|
-
appearance={themeMode !==
|
|
108
|
+
appearance={themeMode !== "auto" ? themeMode : undefined}
|
|
107
109
|
className={cx(styles.app, styles.scrollbar, styles.scrollbarPolyfill)}
|
|
108
110
|
customTheme={{
|
|
109
111
|
neutralColor: neutralColor,
|
|
110
112
|
primaryColor: primaryColor,
|
|
111
113
|
}}
|
|
114
|
+
customFonts={[HarmonyOS_Sans_Regular]}
|
|
112
115
|
theme={{
|
|
113
116
|
cssVar: true,
|
|
114
117
|
token: {
|
|
115
|
-
motion: animationMode !==
|
|
116
|
-
motionUnit: animationMode ===
|
|
118
|
+
motion: animationMode !== "disabled",
|
|
119
|
+
motionUnit: animationMode === "agile" ? 0.05 : 0.1,
|
|
117
120
|
},
|
|
118
121
|
}}
|
|
119
122
|
themeMode={themeMode}
|
|
120
|
-
onAppearanceChange={appearance => {
|
|
121
|
-
if (themeMode !==
|
|
123
|
+
onAppearanceChange={(appearance) => {
|
|
124
|
+
if (themeMode !== "auto") return;
|
|
122
125
|
|
|
123
126
|
setCookie(CLOUD_THEME_APPEARANCE, appearance);
|
|
124
127
|
}}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const SAFE_KEY = /^[^.[\]]+$/;
|
|
2
|
+
|
|
3
|
+
export const toLodashPath = (segments: Array<number | string>) => {
|
|
4
|
+
let path = '';
|
|
5
|
+
|
|
6
|
+
for (const segment of segments) {
|
|
7
|
+
if (typeof segment === 'number') {
|
|
8
|
+
path += `[${segment}]`;
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const key = segment;
|
|
13
|
+
const safe = SAFE_KEY.test(key);
|
|
14
|
+
if (safe) {
|
|
15
|
+
path += path ? `.${key}` : key;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
path += `[${JSON.stringify(key)}]`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return path;
|
|
23
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Root } from "react-dom";
|
|
2
|
+
import { renderClient } from "@config/router";
|
|
3
|
+
import { createRouter } from "@/routes";
|
|
4
|
+
|
|
5
|
+
interface GarfishProvider {
|
|
6
|
+
render: (props: { basename: string }) => void;
|
|
7
|
+
destroy: () => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface RenderContext {
|
|
11
|
+
basename?: string;
|
|
12
|
+
rootElement: HTMLElement | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Garfish 微前端生命周期适配器
|
|
17
|
+
*/
|
|
18
|
+
export function createGarfishProvider(appName: string): GarfishProvider {
|
|
19
|
+
let root: Root | null = null;
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
render({ basename }: { basename: string }) {
|
|
23
|
+
const context: RenderContext = {
|
|
24
|
+
basename,
|
|
25
|
+
rootElement: document.getElementById(appName) ?? document.body,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
root = renderClient(context);
|
|
29
|
+
|
|
30
|
+
// 向主应用通知路由信息
|
|
31
|
+
if (window.Garfish?.channel) {
|
|
32
|
+
window.Garfish.channel.emit("router", {
|
|
33
|
+
name: appName,
|
|
34
|
+
routes: createRouter(basename),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
destroy() {
|
|
40
|
+
if (root) {
|
|
41
|
+
root.unmount();
|
|
42
|
+
root = null;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 判断是否在微前端环境中运行
|
|
50
|
+
*/
|
|
51
|
+
export function isMicroApp(): boolean {
|
|
52
|
+
return typeof window !== "undefined" && Boolean(window.__GARFISH__);
|
|
53
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { optionalDevtools } from
|
|
2
|
-
import type { devtools as _devtools } from
|
|
1
|
+
import { optionalDevtools } from "zustand-utils";
|
|
2
|
+
import type { devtools as _devtools } from "zustand/middleware";
|
|
3
3
|
|
|
4
|
-
import { isDev } from
|
|
4
|
+
import { isDev } from "@/config/env";
|
|
5
5
|
|
|
6
6
|
export const createDevtools =
|
|
7
7
|
(name: string): typeof _devtools =>
|
|
8
|
-
initializer => {
|
|
8
|
+
(initializer) => {
|
|
9
9
|
let showDevtools = false;
|
|
10
10
|
|
|
11
11
|
// check url to show devtools
|
|
12
|
-
if (typeof window !==
|
|
12
|
+
if (typeof window !== "undefined") {
|
|
13
13
|
const url = new URL(window.location.href);
|
|
14
|
-
const debug = url.searchParams.get(
|
|
14
|
+
const debug = url.searchParams.get("debug");
|
|
15
15
|
if (debug?.includes(name)) {
|
|
16
16
|
showDevtools = true;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
return optionalDevtools(showDevtools)(initializer, {
|
|
21
|
-
name: `LobeChat_${name}${isDev ?
|
|
21
|
+
name: `LobeChat_${name}${isDev ? "_DEV" : ""}`,
|
|
22
22
|
});
|
|
23
23
|
};
|
|
@@ -8,11 +8,10 @@
|
|
|
8
8
|
"dev:test": "cross-env NODE_ENV=testDevelopment rspack serve --config config/rspack/rspack.dev.mjs",
|
|
9
9
|
"build:test": "cross-env NODE_ENV=test rspack build --config config/rspack/rspack.prod.mjs --mode production",
|
|
10
10
|
"build": "cross-env NODE_ENV=production rspack build --config config/rspack/rspack.prod.mjs --mode production",
|
|
11
|
-
"test": "jest",
|
|
12
11
|
"lint": "biome check",
|
|
13
|
-
"test:watch": "jest --watch",
|
|
14
|
-
"test:coverage": "jest --coverage",
|
|
15
12
|
"prepare": "husky install",
|
|
13
|
+
"i18n": "npm run workflow:i18n && lobe-i18n && prettier -c --write \"locales/**\"",
|
|
14
|
+
"workflow:i18n": "tsx ./scripts/i18nWorkflow/index.ts",
|
|
16
15
|
"test:ci": "jest --coverage --watchAll=false"
|
|
17
16
|
},
|
|
18
17
|
"engines": {
|
|
@@ -29,7 +28,7 @@
|
|
|
29
28
|
"@tanstack/react-query": "^5.80.6",
|
|
30
29
|
"ahooks": "^3.8.5",
|
|
31
30
|
"antd": "^6.1.1",
|
|
32
|
-
"antd-style": "^
|
|
31
|
+
"antd-style": "^4.0.0",
|
|
33
32
|
"clsx": "^2.1.1",
|
|
34
33
|
"copy-webpack-plugin": "^13.0.1",
|
|
35
34
|
"dayjs": "^1.11.13",
|
|
@@ -53,26 +52,16 @@
|
|
|
53
52
|
"resolve-accept-language": "^3.1.11",
|
|
54
53
|
"rtl-detect": "^1.1.2",
|
|
55
54
|
"rxjs": "^7.8.2",
|
|
56
|
-
"styled-components": "^5.3.11",
|
|
57
55
|
"tailwind-merge": "^3.3.0",
|
|
58
56
|
"tailwindcss": "^4.1.8",
|
|
59
57
|
"universal-cookie": "^8.0.1",
|
|
60
58
|
"url-join": "^5.0.0",
|
|
61
59
|
"uuid": "^11.0.3",
|
|
60
|
+
"zod": "^4.2.1",
|
|
62
61
|
"zustand": "^5.0.5",
|
|
63
62
|
"zustand-utils": "^2.1.1"
|
|
64
63
|
},
|
|
65
64
|
"devDependencies": {
|
|
66
|
-
"@babel/core": "^7.26.0",
|
|
67
|
-
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
68
|
-
"@babel/plugin-proposal-decorators": "^7.25.9",
|
|
69
|
-
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
|
|
70
|
-
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
71
|
-
"@babel/plugin-transform-runtime": "^7.25.9",
|
|
72
|
-
"@babel/preset-env": "^7.26.0",
|
|
73
|
-
"@babel/preset-react": "^7.25.9",
|
|
74
|
-
"@babel/runtime": "^7.26.0",
|
|
75
|
-
"@babel/runtime-corejs3": "^7.26.0",
|
|
76
65
|
"@biomejs/biome": "2.3.2",
|
|
77
66
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
|
|
78
67
|
"@rsdoctor/rspack-plugin": "^1.3.8",
|
|
@@ -80,16 +69,13 @@
|
|
|
80
69
|
"@rspack/cli": "^1.1.8",
|
|
81
70
|
"@rspack/core": "^1.1.8",
|
|
82
71
|
"@svgr/webpack": "^7.0.0",
|
|
83
|
-
"@testing-library/jest-dom": "^6.6.3",
|
|
84
|
-
"@testing-library/react": "^16.3.0",
|
|
85
|
-
"@testing-library/user-event": "^14.6.1",
|
|
86
|
-
"@types/jest": "^29.5.14",
|
|
87
72
|
"@types/lodash-es": "^4.17.12",
|
|
88
73
|
"@types/node": "^22.9.0",
|
|
89
74
|
"@types/react": "^19.1.6",
|
|
90
75
|
"@types/react-dom": "^19.1.6",
|
|
91
76
|
"@types/react-resizable": "^3.0.8",
|
|
92
|
-
"@
|
|
77
|
+
"@prettier/sync": "^0.6.1",
|
|
78
|
+
"@lobehub/i18n-cli": "^1.26.0",
|
|
93
79
|
"assert": "^2.1.0",
|
|
94
80
|
"autoprefixer": "^10.4.20",
|
|
95
81
|
"axios": "^1.6.8",
|
|
@@ -97,6 +83,7 @@
|
|
|
97
83
|
"browserify-zlib": "^0.2.0",
|
|
98
84
|
"buffer": "^6.0.3",
|
|
99
85
|
"chokidar": "^4.0.3",
|
|
86
|
+
"consola": "^3.4.2",
|
|
100
87
|
"clean-webpack-plugin": "^4.0.0",
|
|
101
88
|
"cross-env": "^7.0.3",
|
|
102
89
|
"crypto-browserify": "^3.12.1",
|
|
@@ -109,10 +96,6 @@
|
|
|
109
96
|
"globals": "^16.3.0",
|
|
110
97
|
"html-webpack-plugin": "^5.6.3",
|
|
111
98
|
"husky": "^9.1.7",
|
|
112
|
-
"jest": "^29.7.0",
|
|
113
|
-
"jest-environment-jsdom": "30.0.0-beta.3",
|
|
114
|
-
"jiti": "^2.5.1",
|
|
115
|
-
"js-cookie": "^2.2.1",
|
|
116
99
|
"less": "^4.2.0",
|
|
117
100
|
"less-loader": "^12.2.0",
|
|
118
101
|
"lint-staged": "^16.1.6",
|
|
@@ -130,11 +113,11 @@
|
|
|
130
113
|
"stream-browserify": "^3.0.0",
|
|
131
114
|
"style-loader": "^3.3.4",
|
|
132
115
|
"terser-webpack-plugin": "^5.3.11",
|
|
133
|
-
"ts-jest": "^29.3.4",
|
|
134
116
|
"ts-loader": "^9.5.1",
|
|
135
117
|
"typescript": "^5.6.3",
|
|
136
118
|
"url": "^0.11.4",
|
|
137
119
|
"util": "^0.12.5",
|
|
120
|
+
"tsx": "^4.21.0",
|
|
138
121
|
"webpack-merge": "^6.0.1"
|
|
139
122
|
},
|
|
140
123
|
"lint-staged": {
|
package/dist/templates/page.tsx
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Button } from 'antd';
|
|
1
|
+
import UnFindPng from '@config/public/404.png';
|
|
2
|
+
import { Button, Empty } from 'antd';
|
|
3
3
|
import React from 'react';
|
|
4
|
+
import { useNavigate } from 'react-router';
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
-
const
|
|
7
|
-
const setTheme = useThemeStore(state => state.setTheme);
|
|
6
|
+
export const UnPageFind = () => {
|
|
7
|
+
const navigate = useNavigate();
|
|
8
8
|
|
|
9
9
|
return (
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
<div className='p-4 w-full h-full relative flex justify-center items-center'>
|
|
11
|
+
<Empty
|
|
12
|
+
image={UnFindPng}
|
|
13
|
+
description={
|
|
14
|
+
<div className='flex flex-col gap-2 justify-center items-center'>
|
|
15
|
+
<h2>抱歉,页面无法访问…</h2>
|
|
16
|
+
<span>404,网址错误或已失效。请检查网址。</span>
|
|
17
|
+
<Button size={'large'} type={'primary'} className='w-24' onClick={() => navigate('/')}>
|
|
18
|
+
返回首页
|
|
19
|
+
</Button>
|
|
20
|
+
</div>
|
|
16
21
|
}
|
|
17
|
-
>
|
|
18
|
-
|
|
19
|
-
</button>
|
|
20
|
-
<button type="button" onClick={() => setTheme('dark')}>
|
|
21
|
-
切换主题({theme})
|
|
22
|
-
</button>
|
|
23
|
-
</>
|
|
22
|
+
></Empty>
|
|
23
|
+
</div>
|
|
24
24
|
);
|
|
25
|
-
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default UnPageFind;
|