@lobehub/lobehub 2.0.0-next.342 → 2.0.0-next.344

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/changelog/v1.json +21 -0
  3. package/package.json +1 -1
  4. package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +161 -12
  5. package/packages/database/src/models/__tests__/userMemories.test.ts +62 -5
  6. package/packages/database/src/models/agentCronJob.ts +9 -9
  7. package/packages/database/src/models/userMemory/__tests__/identity.test.ts +5 -5
  8. package/packages/database/src/models/userMemory/experience.ts +91 -1
  9. package/packages/database/src/models/userMemory/identity.ts +93 -2
  10. package/packages/database/src/models/userMemory/model.ts +27 -8
  11. package/packages/types/src/userMemory/experience.ts +25 -0
  12. package/packages/types/src/userMemory/identity.ts +27 -0
  13. package/packages/types/src/userMemory/index.ts +1 -0
  14. package/packages/types/src/userMemory/shared.ts +30 -0
  15. package/src/app/[variants]/(main)/group/profile/features/Header/index.tsx +3 -4
  16. package/src/app/[variants]/(main)/home/features/InputArea/SkillInstallBanner.tsx +7 -8
  17. package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaDetail.tsx +58 -0
  18. package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaHeader.tsx +22 -0
  19. package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaSummary.tsx +43 -0
  20. package/src/app/[variants]/(main)/memory/(home)/features/Persona/index.tsx +53 -0
  21. package/src/app/[variants]/(main)/memory/(home)/features/RoleTagCloud/index.tsx +2 -2
  22. package/src/app/[variants]/(main)/memory/(home)/index.tsx +15 -3
  23. package/src/app/[variants]/(main)/memory/experiences/features/List/GridView/ExperienceCard.tsx +3 -3
  24. package/src/app/[variants]/(main)/memory/experiences/features/List/GridView/index.tsx +3 -3
  25. package/src/app/[variants]/(main)/memory/experiences/features/List/TimelineView/ExperienceCard.tsx +3 -3
  26. package/src/app/[variants]/(main)/memory/experiences/features/List/TimelineView/index.tsx +3 -3
  27. package/src/app/[variants]/(main)/memory/features/SourceLink.tsx +2 -11
  28. package/src/app/[variants]/(main)/memory/features/TimeLineView/TimeLineCard.tsx +2 -9
  29. package/src/app/[variants]/(main)/memory/identities/features/IdentityRightPanel.tsx +1 -1
  30. package/src/app/[variants]/(main)/memory/identities/features/List/GridView/IdentityCard.tsx +5 -4
  31. package/src/app/[variants]/(main)/memory/identities/features/List/GridView/index.tsx +3 -3
  32. package/src/app/[variants]/(main)/memory/identities/features/List/TimelineView/IdentityCard.tsx +6 -6
  33. package/src/app/[variants]/(main)/memory/identities/features/List/TimelineView/index.tsx +6 -4
  34. package/src/app/[variants]/(main)/settings/profile/index.tsx +8 -8
  35. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +0 -1
  36. package/src/app/[variants]/(main)/settings/skill/features/Actions.tsx +0 -1
  37. package/src/app/[variants]/(main)/settings/skill/features/KlavisSkillItem.tsx +9 -10
  38. package/src/app/[variants]/(main)/settings/skill/features/LobehubSkillItem.tsx +9 -10
  39. package/src/app/[variants]/(main)/settings/skill/features/McpSkillItem.tsx +4 -5
  40. package/src/app/[variants]/(main)/settings/skill/features/SkillList.tsx +4 -5
  41. package/src/app/[variants]/share/t/[id]/SharedMessageList.tsx +1 -4
  42. package/src/app/[variants]/share/t/[id]/_layout/index.tsx +47 -121
  43. package/src/app/[variants]/share/t/[id]/_layout/style.ts +59 -0
  44. package/src/app/[variants]/share/t/[id]/features/Portal/index.tsx +4 -5
  45. package/src/app/[variants]/share/t/[id]/index.tsx +30 -37
  46. package/src/components/404/index.tsx +15 -9
  47. package/src/components/DragUpload/index.tsx +15 -16
  48. package/src/features/EditorCanvas/DocumentIdMode.tsx +1 -2
  49. package/src/features/IntegrationDetailModal/index.tsx +11 -12
  50. package/src/features/ResourceManager/index.tsx +13 -6
  51. package/src/features/ShareModal/ShareImage/Preview.tsx +19 -28
  52. package/src/features/ShareModal/ShareImage/style.ts +4 -2
  53. package/src/features/ShareModal/index.tsx +5 -1
  54. package/src/features/ShareModal/style.ts +1 -0
  55. package/src/features/ShareModal/useContainerStyles.ts +1 -1
  56. package/src/features/SharePopover/index.tsx +16 -9
  57. package/src/features/SharePopover/style.ts +2 -2
  58. package/src/features/SkillStore/CommunityList/Item.tsx +2 -2
  59. package/src/features/SkillStore/LobeHubList/Item.tsx +2 -2
  60. package/src/features/SkillStore/LobeHubList/index.tsx +2 -3
  61. package/src/features/SkillStore/style.ts +4 -4
  62. package/src/layout/GlobalProvider/ServerVersionOutdatedAlert.tsx +28 -20
  63. package/src/server/routers/lambda/userMemories.ts +61 -5
  64. package/src/server/routers/lambda/userMemory.ts +5 -1
  65. package/src/services/chat/index.ts +2 -2
  66. package/src/services/userMemory/index.ts +25 -1
  67. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +0 -1
  68. package/src/store/userMemory/initialState.ts +22 -52
  69. package/src/store/userMemory/slices/context/action.ts +1 -1
  70. package/src/store/userMemory/slices/context/index.ts +1 -0
  71. package/src/store/userMemory/slices/context/initialState.ts +22 -0
  72. package/src/store/userMemory/slices/experience/action.ts +10 -22
  73. package/src/store/userMemory/slices/experience/index.ts +1 -0
  74. package/src/store/userMemory/slices/experience/initialState.ts +22 -0
  75. package/src/store/userMemory/slices/home/action.ts +17 -0
  76. package/src/store/userMemory/slices/identity/action.ts +36 -24
  77. package/src/store/userMemory/slices/identity/initialState.ts +7 -4
  78. package/src/store/userMemory/slices/preference/action.ts +1 -1
  79. package/src/store/userMemory/slices/preference/index.ts +1 -0
  80. package/src/store/userMemory/slices/preference/initialState.ts +22 -0
@@ -1,6 +1,5 @@
1
1
  'use client';
2
2
 
3
- import { Flexbox } from '@lobehub/ui';
4
3
  import { memo, useCallback, useMemo } from 'react';
5
4
 
6
5
  import { ChatList, ConversationProvider, MessageItem } from '@/features/Conversation';
@@ -44,9 +43,7 @@ const SharedMessageList = memo<SharedMessageListProps>(({ agentId, groupId, shar
44
43
  replaceMessages(messages, { context: ctx });
45
44
  }}
46
45
  >
47
- <Flexbox flex={1}>
48
- <ChatList disableActionsBar itemContent={itemContent} />
49
- </Flexbox>
46
+ <ChatList disableActionsBar itemContent={itemContent} />
50
47
  </ConversationProvider>
51
48
  );
52
49
  });
@@ -1,52 +1,27 @@
1
1
  'use client';
2
2
 
3
- import { Avatar, Flexbox } from '@lobehub/ui';
4
- import { Typography } from 'antd';
5
- import { createStyles, cssVar } from 'antd-style';
3
+ import { Alert, Center, Flexbox, Text } from '@lobehub/ui';
4
+ import { cx } from 'antd-style';
6
5
  import NextLink from 'next/link';
7
- import { PropsWithChildren, memo, useEffect, useMemo } from 'react';
6
+ import { PropsWithChildren, memo, useEffect } from 'react';
8
7
  import { useTranslation } from 'react-i18next';
9
8
  import { Link, Outlet, useParams } from 'react-router-dom';
10
9
  import useSWR from 'swr';
11
10
 
12
11
  import { ProductLogo } from '@/components/Branding';
13
- import { DEFAULT_AVATAR } from '@/const/meta';
14
- import GroupAvatar from '@/features/GroupAvatar';
15
12
  import UserAvatar from '@/features/User/UserAvatar';
13
+ import { useIsDark } from '@/hooks/useIsDark';
16
14
  import { lambdaClient } from '@/libs/trpc/client';
17
15
  import { useAgentStore } from '@/store/agent';
18
16
  import { useUserStore } from '@/store/user';
19
17
  import { authSelectors } from '@/store/user/slices/auth/selectors';
20
18
 
21
19
  import SharePortal from '../features/Portal';
22
-
23
- const useStyles = createStyles(({ css, token }) => ({
24
- container: css`
25
- width: 100vw;
26
- min-height: 100vh;
27
- background: ${token.colorBgLayout};
28
- `,
29
- content: css`
30
- flex: 1;
31
- width: 100%;
32
- padding-block: 24px;
33
- padding-inline: 24px;
34
- `,
35
- footer: css`
36
- padding-block: 16px;
37
- padding-inline: 24px;
38
- color: ${token.colorTextTertiary};
39
- text-align: center;
40
- `,
41
- header: css`
42
- height: 52px;
43
- padding: 8px;
44
- `,
45
- }));
20
+ import { styles } from './style';
46
21
 
47
22
  const ShareTopicLayout = memo<PropsWithChildren>(({ children }) => {
48
- const { styles } = useStyles();
49
23
  const { t } = useTranslation('chat');
24
+ const isDarkMode = useIsDark();
50
25
  const { id } = useParams<{ id: string }>();
51
26
  const dispatchAgentMap = useAgentStore((s) => s.internal_dispatchAgentMap);
52
27
  const isLogin = useUserStore(authSelectors.isLogin);
@@ -69,100 +44,51 @@ const ShareTopicLayout = memo<PropsWithChildren>(({ children }) => {
69
44
  }
70
45
  }, [data?.agentId, data?.agentMeta, dispatchAgentMap]);
71
46
 
72
- const isGroup = !!data?.groupId;
73
- const isInboxAgent = !isGroup && data?.agentMeta?.slug === 'inbox';
74
- const agentOrGroupTitle =
75
- data?.groupMeta?.title || (isInboxAgent ? 'LobeAI' : data?.agentMeta?.title);
76
- const agentMarketIdentifier = data?.agentMeta?.marketIdentifier;
77
-
78
- // Build group avatars for GroupAvatar component
79
- const groupAvatars = useMemo(() => {
80
- if (!isGroup || !data?.groupMeta?.members) return [];
81
- return data.groupMeta.members.map((member) => ({
82
- avatar: member.avatar || DEFAULT_AVATAR,
83
- backgroundColor: member.backgroundColor || undefined,
84
- }));
85
- }, [isGroup, data?.groupMeta?.members]);
86
-
87
- const renderAgentOrGroupAvatar = () => {
88
- // For group: use GroupAvatar with members
89
- if (isGroup && groupAvatars.length > 0) {
90
- return <GroupAvatar avatars={groupAvatars} size={24} />;
91
- }
92
-
93
- // For inbox agent: skip avatar as it's the same as product icon
94
- if (isInboxAgent) {
95
- return null;
96
- }
97
-
98
- // For agent: use single Avatar
99
- if (data?.agentMeta?.avatar) {
100
- return (
101
- <Avatar
102
- avatar={data.agentMeta.avatar}
103
- background={data.agentMeta.backgroundColor || cssVar.colorFillTertiary}
104
- shape="square"
105
- size={24}
106
- />
107
- );
108
- }
109
-
110
- return null;
111
- };
112
-
113
- const renderAgentOrGroupTitle = () => {
114
- if (!agentOrGroupTitle) return null;
115
-
116
- // If agent has marketIdentifier, render as link to assistant page
117
- if (agentMarketIdentifier && !data?.groupMeta?.title) {
118
- return (
119
- <a href={`/community/agent/${agentMarketIdentifier}`} rel="noreferrer" target="_blank">
120
- <Typography.Text ellipsis strong>
121
- {agentOrGroupTitle}
122
- </Typography.Text>
123
- </a>
124
- );
125
- }
126
-
127
- return (
128
- <Typography.Text ellipsis strong>
129
- {agentOrGroupTitle}
130
- </Typography.Text>
131
- );
132
- };
133
-
134
47
  return (
135
- <Flexbox className={styles.container}>
136
- <Flexbox align="center" className={styles.header} gap={12} horizontal justify="space-between">
137
- <Flexbox align="center" flex={1} gap={12} horizontal>
138
- {isLogin ? (
139
- <Link to="/">
140
- <ProductLogo size={24} />
141
- </Link>
142
- ) : (
143
- <NextLink href="/login">
144
- <ProductLogo size={24} />
145
- </NextLink>
146
- )}
147
- {renderAgentOrGroupAvatar()}
148
- {renderAgentOrGroupTitle()}
48
+ <Flexbox className={styles.outerContainer} height={'100%'} padding={8} width={'100%'}>
49
+ <Flexbox
50
+ className={cx(isDarkMode ? styles.innerContainerDark : styles.innerContainerLight)}
51
+ height={'100%'}
52
+ width={'100%'}
53
+ >
54
+ <Flexbox
55
+ align={'center'}
56
+ gap={8}
57
+ horizontal
58
+ justify={'space-between'}
59
+ padding={8}
60
+ width={'100%'}
61
+ >
62
+ <Flexbox align="center" flex={1} gap={12} horizontal>
63
+ {isLogin ? (
64
+ <Link to="/">
65
+ <UserAvatar size={32} />
66
+ </Link>
67
+ ) : (
68
+ <NextLink href="/login">
69
+ <ProductLogo size={32} />
70
+ </NextLink>
71
+ )}
72
+ </Flexbox>
73
+ <Center flex={2} gap={12} horizontal>
74
+ {data?.title && (
75
+ <Text align={'center'} ellipsis style={{ textAlign: 'center' }} weight={500}>
76
+ {data.title}
77
+ </Text>
78
+ )}
79
+ </Center>
80
+ <Flexbox align="center" flex={1} gap={12} horizontal justify={'flex-end'} />
149
81
  </Flexbox>
150
- {data?.title && (
151
- <Typography.Text ellipsis strong style={{ textAlign: 'center' }}>
152
- {data.title}
153
- </Typography.Text>
154
- )}
155
- <Flexbox align="center" flex={1} horizontal justify="flex-end">
156
- {isLogin && <UserAvatar size={24} />}
157
- </Flexbox>
158
- </Flexbox>
159
- <Flexbox className={styles.content} horizontal style={{ overflow: 'hidden' }}>
160
- <Flexbox flex={1} style={{ overflow: 'hidden' }}>
161
- {children ?? <Outlet />}
82
+ <Flexbox className={styles.content} horizontal style={{ overflow: 'hidden' }}>
83
+ <Flexbox flex={1} style={{ overflow: 'hidden' }}>
84
+ {children ?? <Outlet />}
85
+ </Flexbox>
86
+ <SharePortal />
162
87
  </Flexbox>
163
- <SharePortal />
88
+ <Center padding={8} style={{ opacity: 0.25 }}>
89
+ <Alert title={t('sharePageDisclaimer')} type={'secondary'} variant={'borderless'} />
90
+ </Center>
164
91
  </Flexbox>
165
- <Typography.Text className={styles.footer}>{t('sharePageDisclaimer')}</Typography.Text>
166
92
  </Flexbox>
167
93
  );
168
94
  });
@@ -0,0 +1,59 @@
1
+ import { createStaticStyles } from 'antd-style';
2
+
3
+ export const styles = createStaticStyles(({ css, cssVar }) => ({
4
+ container: css`
5
+ width: 100vw;
6
+ min-height: 100vh;
7
+ background: ${cssVar.colorBgLayout};
8
+ `,
9
+
10
+ content: css`
11
+ flex: 1;
12
+ width: 100%;
13
+ `,
14
+
15
+ // Divider 样式
16
+ divider: css`
17
+ height: 24px;
18
+ `,
19
+
20
+ footer: css`
21
+ padding-block: 16px;
22
+ padding-inline: 24px;
23
+ color: ${cssVar.colorTextTertiary};
24
+ text-align: center;
25
+ `,
26
+
27
+ header: css`
28
+ height: 52px;
29
+ padding: 8px;
30
+ `,
31
+
32
+ // 内层容器 - 深色模式
33
+ innerContainerDark: css`
34
+ position: relative;
35
+
36
+ overflow: hidden;
37
+
38
+ border: 1px solid ${cssVar.colorBorderSecondary};
39
+ border-radius: ${cssVar.borderRadius};
40
+
41
+ background: ${cssVar.colorBgContainer};
42
+ `,
43
+
44
+ // 内层容器 - 浅色模式
45
+ innerContainerLight: css`
46
+ position: relative;
47
+
48
+ overflow: hidden;
49
+
50
+ border: 1px solid ${cssVar.colorBorder};
51
+ border-radius: ${cssVar.borderRadius};
52
+
53
+ background: ${cssVar.colorBgContainer};
54
+ `,
55
+ // 外层容器
56
+ outerContainer: css`
57
+ position: relative;
58
+ `,
59
+ }));
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { DraggablePanel } from '@lobehub/ui';
4
- import { createStyles } from 'antd-style';
4
+ import { createStaticStyles } from 'antd-style';
5
5
  import { memo } from 'react';
6
6
 
7
7
  import { CHAT_PORTAL_TOOL_UI_WIDTH } from '@/const/layoutTokens';
@@ -9,7 +9,7 @@ import { PortalContent } from '@/features/Portal/router';
9
9
  import { useChatStore } from '@/store/chat';
10
10
  import { chatPortalSelectors } from '@/store/chat/selectors';
11
11
 
12
- const useStyles = createStyles(({ css, token }) => ({
12
+ const styles = createStaticStyles(({ cssVar, css }) => ({
13
13
  body: css`
14
14
  overflow: hidden;
15
15
  display: flex;
@@ -30,17 +30,16 @@ const useStyles = createStyles(({ css, token }) => ({
30
30
  min-height: 100%;
31
31
  max-height: 100%;
32
32
 
33
- background: ${token.colorBgContainer};
33
+ background: ${cssVar.colorBgContainer};
34
34
  `,
35
35
  drawer: css`
36
36
  z-index: 10;
37
37
  height: 100%;
38
- background: ${token.colorBgContainer};
38
+ background: ${cssVar.colorBgContainer};
39
39
  `,
40
40
  }));
41
41
 
42
42
  const SharePortal = memo(() => {
43
- const { styles } = useStyles();
44
43
  const showPortal = useChatStore(chatPortalSelectors.showPortal);
45
44
 
46
45
  return (
@@ -1,29 +1,27 @@
1
1
  'use client';
2
2
 
3
- import { Flexbox } from '@lobehub/ui';
3
+ import { Button, Center } from '@lobehub/ui';
4
4
  import { TRPCClientError } from '@trpc/client';
5
- import { Button, Result, Skeleton } from 'antd';
6
- import { createStyles } from 'antd-style';
5
+ import { createStaticStyles } from 'antd-style';
7
6
  import { memo } from 'react';
8
7
  import { useTranslation } from 'react-i18next';
9
8
  import { useParams } from 'react-router-dom';
10
9
  import useSWR from 'swr';
11
10
 
11
+ import NotFound from '@/components/404';
12
+ import Loading from '@/components/Loading/BrandTextLoading';
12
13
  import { lambdaClient } from '@/libs/trpc/client';
13
14
 
14
15
  import SharedMessageList from './SharedMessageList';
15
16
 
16
- const useStyles = createStyles(({ css }) => ({
17
- container: css`
18
- flex: 1;
19
- `,
17
+ const styles = createStaticStyles(({ css }) => ({
20
18
  errorContainer: css`
21
19
  display: flex;
22
20
  flex-direction: column;
23
21
  align-items: center;
24
22
  justify-content: center;
25
23
 
26
- min-height: 400px;
24
+ height: 80vh;
27
25
  padding: 48px;
28
26
 
29
27
  text-align: center;
@@ -31,7 +29,6 @@ const useStyles = createStyles(({ css }) => ({
31
29
  }));
32
30
 
33
31
  const ShareTopicPage = memo(() => {
34
- const { styles } = useStyles();
35
32
  const { t } = useTranslation('chat');
36
33
  const { id } = useParams<{ id: string }>();
37
34
 
@@ -41,12 +38,11 @@ const ShareTopicPage = memo(() => {
41
38
  { revalidateOnFocus: false },
42
39
  );
43
40
 
44
- if (isLoading) {
41
+ if (!error && isLoading) {
45
42
  return (
46
- <Flexbox className={styles.container} gap={16}>
47
- <Skeleton active paragraph={{ rows: 1 }} title={false} />
48
- <Skeleton active paragraph={{ rows: 6 }} />
49
- </Flexbox>
43
+ <Center className={styles.errorContainer}>
44
+ <Loading debugId="share" />
45
+ </Center>
50
46
  );
51
47
  }
52
48
 
@@ -56,56 +52,53 @@ const ShareTopicPage = memo(() => {
56
52
 
57
53
  if (errorCode === 'UNAUTHORIZED') {
58
54
  return (
59
- <Flexbox className={styles.errorContainer}>
60
- <Result
55
+ <Center className={styles.errorContainer}>
56
+ <NotFound
57
+ desc={t('sharePage.error.unauthorized.subtitle')}
61
58
  extra={
62
59
  <Button href="/login" type="primary">
63
60
  {t('sharePage.error.unauthorized.action')}
64
61
  </Button>
65
62
  }
66
- status="403"
67
- subTitle={t('sharePage.error.unauthorized.subtitle')}
63
+ status={''}
68
64
  title={t('sharePage.error.unauthorized.title')}
69
65
  />
70
- </Flexbox>
66
+ </Center>
71
67
  );
72
68
  }
73
69
 
74
70
  if (errorCode === 'FORBIDDEN') {
75
71
  return (
76
- <Flexbox className={styles.errorContainer}>
77
- <Result
78
- status="403"
79
- subTitle={t('sharePage.error.forbidden.subtitle')}
72
+ <Center className={styles.errorContainer}>
73
+ <NotFound
74
+ desc={t('sharePage.error.forbidden.subtitle')}
75
+ status={403}
80
76
  title={t('sharePage.error.forbidden.title')}
81
77
  />
82
- </Flexbox>
78
+ </Center>
83
79
  );
84
80
  }
85
81
 
86
82
  // NOT_FOUND or other errors
87
83
  return (
88
- <Flexbox className={styles.errorContainer}>
89
- <Result
90
- status="404"
91
- subTitle={t('sharePage.error.notFound.subtitle')}
84
+ <Center className={styles.errorContainer}>
85
+ <NotFound
86
+ desc={t('sharePage.error.notFound.subtitle')}
92
87
  title={t('sharePage.error.notFound.title')}
93
88
  />
94
- </Flexbox>
89
+ </Center>
95
90
  );
96
91
  }
97
92
 
98
93
  if (!data) return null;
99
94
 
100
95
  return (
101
- <Flexbox className={styles.container}>
102
- <SharedMessageList
103
- agentId={data.agentId}
104
- groupId={data.groupId}
105
- shareId={data.shareId}
106
- topicId={data.topicId}
107
- />
108
- </Flexbox>
96
+ <SharedMessageList
97
+ agentId={data.agentId}
98
+ groupId={data.groupId}
99
+ shareId={data.shareId}
100
+ topicId={data.topicId}
101
+ />
109
102
  );
110
103
  });
111
104
 
@@ -1,12 +1,17 @@
1
1
  'use client';
2
2
 
3
3
  import { Button, Flexbox, FluentEmoji } from '@lobehub/ui';
4
- import { memo } from 'react';
4
+ import { ReactNode, memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { MAX_WIDTH } from '@/const/layoutTokens';
8
8
 
9
- const NotFound = memo(() => {
9
+ const NotFound = memo<{
10
+ desc?: string;
11
+ extra?: ReactNode;
12
+ status?: number | string;
13
+ title?: string;
14
+ }>(({ extra, status = 404, title, desc }) => {
10
15
  const { t } = useTranslation('error');
11
16
  return (
12
17
  <Flexbox align={'center'} justify={'center'} style={{ minHeight: '100%', width: '100%' }}>
@@ -21,20 +26,21 @@ const NotFound = memo(() => {
21
26
  zIndex: 0,
22
27
  }}
23
28
  >
24
- 404
29
+ {status}
25
30
  </h1>
26
31
  <FluentEmoji emoji={'👀'} size={64} />
27
32
  <h2 style={{ fontWeight: 'bold', marginTop: '1em', textAlign: 'center' }}>
28
- {t('notFound.title')}
33
+ {title || t('notFound.title')}
29
34
  </h2>
30
35
  <div style={{ lineHeight: '1.8', marginBottom: '2em', textAlign: 'center' }}>
31
- <div>{t('notFound.desc')}</div>
36
+ <div>{desc || t('notFound.desc')}</div>
32
37
  <div style={{ marginTop: '0.5em' }}>{t('notFound.check')}</div>
33
38
  </div>
34
-
35
- <Button onClick={() => (window.location.href = '/')} type={'primary'}>
36
- {t('notFound.backHome')}
37
- </Button>
39
+ {extra || (
40
+ <Button onClick={() => (window.location.href = '/')} type={'primary'}>
41
+ {t('notFound.backHome')}
42
+ </Button>
43
+ )}
38
44
  </Flexbox>
39
45
  );
40
46
  });
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-undef */
2
2
  import { Center, Flexbox, Icon } from '@lobehub/ui';
3
- import { createStyles } from 'antd-style';
3
+ import { createStaticStyles } from 'antd-style';
4
4
  import { FileImage, FileText, FileUpIcon } from 'lucide-react';
5
5
  import { memo } from 'react';
6
6
  import { createPortal } from 'react-dom';
@@ -11,22 +11,22 @@ import { getContainer, useDragUpload } from './useDragUpload';
11
11
  const BLOCK_SIZE = 64;
12
12
  const ICON_SIZE = { size: 36, strokeWidth: 1.5 };
13
13
 
14
- const useStyles = createStyles(({ css, token }) => {
14
+ const styles = createStaticStyles(({ css, cssVar }) => {
15
15
  return {
16
16
  container: css`
17
17
  width: 320px;
18
18
  height: 200px;
19
- padding: calc(${token.borderRadiusLG}px + 4px);
19
+ padding: calc(${cssVar.borderRadiusLG} + 4px);
20
20
  border-radius: 16px;
21
21
 
22
- background: ${token.geekblue};
22
+ background: ${cssVar.geekblue};
23
23
  `,
24
24
  content: css`
25
25
  width: 100%;
26
26
  height: 100%;
27
27
  padding: 16px;
28
28
  border: 1.5px dashed #fff;
29
- border-radius: ${token.borderRadiusLG}px;
29
+ border-radius: ${cssVar.borderRadiusLG};
30
30
  `,
31
31
  desc: css`
32
32
  font-size: 14px;
@@ -34,24 +34,24 @@ const useStyles = createStyles(({ css, token }) => {
34
34
  color: #fff;
35
35
  `,
36
36
  icon: css`
37
- border-radius: ${token.borderRadiusLG}px;
38
- color: color-mix(in srgb, ${token.geekblue} 95%, black);
39
- background: color-mix(in srgb, ${token.geekblue} 38%, white);
37
+ border-radius: ${cssVar.borderRadiusLG};
38
+ color: color-mix(in srgb, ${cssVar.geekblue} 95%, black);
39
+ background: color-mix(in srgb, ${cssVar.geekblue} 38%, white);
40
40
  `,
41
41
  iconGroup: css`
42
42
  margin-block-start: -44px;
43
43
  `,
44
44
  iconLeft: css`
45
45
  transform: rotateZ(-20deg) translateX(10px);
46
- border-radius: ${token.borderRadiusLG}px;
47
- color: color-mix(in srgb, ${token.geekblue} 95%, black);
48
- background: color-mix(in srgb, ${token.geekblue} 68%, white);
46
+ border-radius: ${cssVar.borderRadiusLG};
47
+ color: color-mix(in srgb, ${cssVar.geekblue} 95%, black);
48
+ background: color-mix(in srgb, ${cssVar.geekblue} 68%, white);
49
49
  `,
50
50
  iconRight: css`
51
51
  transform: rotateZ(20deg) translateX(-10px);
52
- border-radius: ${token.borderRadiusLG}px;
53
- color: color-mix(in srgb, ${token.geekblue} 95%, black);
54
- background: color-mix(in srgb, ${token.geekblue} 68%, white);
52
+ border-radius: ${cssVar.borderRadiusLG};
53
+ color: color-mix(in srgb, ${cssVar.geekblue} 95%, black);
54
+ background: color-mix(in srgb, ${cssVar.geekblue} 68%, white);
55
55
  `,
56
56
  title: css`
57
57
  font-size: 20px;
@@ -66,7 +66,7 @@ const useStyles = createStyles(({ css, token }) => {
66
66
  width: 100%;
67
67
  height: 100%;
68
68
 
69
- background: ${token.colorBgMask};
69
+ background: ${cssVar.colorBgMask};
70
70
 
71
71
  transition: all 0.3s ease-in-out;
72
72
  `,
@@ -80,7 +80,6 @@ interface DragUploadProps {
80
80
 
81
81
  const DragUpload = memo<DragUploadProps>(({ enabledFiles = true, onUploadFiles }) => {
82
82
  const { t } = useTranslation('components');
83
- const { styles } = useStyles();
84
83
 
85
84
  const isDragging = useDragUpload(onUploadFiles);
86
85
 
@@ -1,8 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { type IEditor } from '@lobehub/editor';
4
- import { Alert } from '@lobehub/ui';
5
- import { Skeleton } from 'antd';
4
+ import { Alert, Skeleton } from '@lobehub/ui';
6
5
  import { memo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import { createStoreUpdater } from 'zustand-utils';