@blocklet/ui-react 3.4.14 → 3.5.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.
Files changed (256) hide show
  1. package/lib/common/org-switch/use-org.d.ts +4 -4
  2. package/lib/common/ws.d.ts +22 -1
  3. package/package.json +10 -7
  4. package/.aigne/doc-smith/.local/afs-storage.sqlite3 +0 -0
  5. package/.aigne/doc-smith/config.yaml +0 -78
  6. package/.aigne/doc-smith/history.yaml +0 -14
  7. package/.aigne/doc-smith/media-description.yaml +0 -11
  8. package/.aigne/doc-smith/output/structure-plan.json +0 -255
  9. package/.aigne/doc-smith/translation-cache.yaml +0 -11
  10. package/.aigne/doc-smith/upload-cache.yaml +0 -528
  11. package/build.config.ts +0 -24
  12. package/docs/_sidebar.md +0 -19
  13. package/docs/assets/diagram/component-installer-diagram-0.ja.jpg +0 -0
  14. package/docs/assets/diagram/component-installer-diagram-0.jpg +0 -0
  15. package/docs/assets/diagram/component-installer-diagram-0.zh-TW.jpg +0 -0
  16. package/docs/assets/diagram/component-installer-diagram-0.zh.jpg +0 -0
  17. package/docs/assets/diagram/component-management-diagram-0.ja.jpg +0 -0
  18. package/docs/assets/diagram/component-management-diagram-0.jpg +0 -0
  19. package/docs/assets/diagram/component-management-diagram-0.zh-TW.jpg +0 -0
  20. package/docs/assets/diagram/component-management-diagram-0.zh.jpg +0 -0
  21. package/docs/assets/diagram/core-concepts-diagram-0.ja.jpg +0 -0
  22. package/docs/assets/diagram/core-concepts-diagram-0.jpg +0 -0
  23. package/docs/assets/diagram/core-concepts-diagram-0.zh-TW.jpg +0 -0
  24. package/docs/assets/diagram/core-concepts-diagram-0.zh.jpg +0 -0
  25. package/docs/assets/diagram/dashboard-diagram-0.ja.jpg +0 -0
  26. package/docs/assets/diagram/dashboard-diagram-0.jpg +0 -0
  27. package/docs/assets/diagram/dashboard-diagram-0.zh-TW.jpg +0 -0
  28. package/docs/assets/diagram/dashboard-diagram-0.zh.jpg +0 -0
  29. package/docs/assets/diagram/header-diagram-0.ja.jpg +0 -0
  30. package/docs/assets/diagram/header-diagram-0.jpg +0 -0
  31. package/docs/assets/diagram/header-diagram-0.zh-TW.jpg +0 -0
  32. package/docs/assets/diagram/header-diagram-0.zh.jpg +0 -0
  33. package/docs/assets/diagram/layout-diagram-0.ja.jpg +0 -0
  34. package/docs/assets/diagram/layout-diagram-0.jpg +0 -0
  35. package/docs/assets/diagram/layout-diagram-0.zh-TW.jpg +0 -0
  36. package/docs/assets/diagram/layout-diagram-0.zh.jpg +0 -0
  37. package/docs/assets/diagram/notifications-diagram-0.ja.jpg +0 -0
  38. package/docs/assets/diagram/notifications-diagram-0.jpg +0 -0
  39. package/docs/assets/diagram/notifications-diagram-0.zh-TW.jpg +0 -0
  40. package/docs/assets/diagram/notifications-diagram-0.zh.jpg +0 -0
  41. package/docs/assets/diagram/overview-diagram-0.ja.jpg +0 -0
  42. package/docs/assets/diagram/overview-diagram-0.jpg +0 -0
  43. package/docs/assets/diagram/overview-diagram-0.zh-TW.jpg +0 -0
  44. package/docs/assets/diagram/overview-diagram-0.zh.jpg +0 -0
  45. package/docs/assets/diagram/user-center-diagram-0.ja.jpg +0 -0
  46. package/docs/assets/diagram/user-center-diagram-0.jpg +0 -0
  47. package/docs/assets/diagram/user-center-diagram-0.zh-TW.jpg +0 -0
  48. package/docs/assets/diagram/user-center-diagram-0.zh.jpg +0 -0
  49. package/docs/assets/diagram/user-management-diagram-0.ja.jpg +0 -0
  50. package/docs/assets/diagram/user-management-diagram-0.jpg +0 -0
  51. package/docs/assets/diagram/user-management-diagram-0.zh-TW.jpg +0 -0
  52. package/docs/assets/diagram/user-management-diagram-0.zh.jpg +0 -0
  53. package/docs/assets/diagram/user-sessions-diagram-0.ja.jpg +0 -0
  54. package/docs/assets/diagram/user-sessions-diagram-0.jpg +0 -0
  55. package/docs/assets/diagram/user-sessions-diagram-0.zh-TW.jpg +0 -0
  56. package/docs/assets/diagram/user-sessions-diagram-0.zh.jpg +0 -0
  57. package/docs/components-component-management-blocklet-studio.ja.md +0 -194
  58. package/docs/components-component-management-blocklet-studio.md +0 -194
  59. package/docs/components-component-management-blocklet-studio.zh-TW.md +0 -194
  60. package/docs/components-component-management-blocklet-studio.zh.md +0 -194
  61. package/docs/components-component-management-component-installer.ja.md +0 -182
  62. package/docs/components-component-management-component-installer.md +0 -182
  63. package/docs/components-component-management-component-installer.zh-TW.md +0 -182
  64. package/docs/components-component-management-component-installer.zh.md +0 -182
  65. package/docs/components-component-management.ja.md +0 -30
  66. package/docs/components-component-management.md +0 -30
  67. package/docs/components-component-management.zh-TW.md +0 -30
  68. package/docs/components-component-management.zh.md +0 -30
  69. package/docs/components-layout-dashboard.ja.md +0 -185
  70. package/docs/components-layout-dashboard.md +0 -187
  71. package/docs/components-layout-dashboard.zh-TW.md +0 -185
  72. package/docs/components-layout-dashboard.zh.md +0 -185
  73. package/docs/components-layout-footer.ja.md +0 -165
  74. package/docs/components-layout-footer.md +0 -165
  75. package/docs/components-layout-footer.zh-TW.md +0 -165
  76. package/docs/components-layout-footer.zh.md +0 -165
  77. package/docs/components-layout-header.ja.md +0 -183
  78. package/docs/components-layout-header.md +0 -183
  79. package/docs/components-layout-header.zh-TW.md +0 -183
  80. package/docs/components-layout-header.zh.md +0 -183
  81. package/docs/components-layout.ja.md +0 -31
  82. package/docs/components-layout.md +0 -31
  83. package/docs/components-layout.zh-TW.md +0 -31
  84. package/docs/components-layout.zh.md +0 -31
  85. package/docs/components-notifications.ja.md +0 -125
  86. package/docs/components-notifications.md +0 -125
  87. package/docs/components-notifications.zh-TW.md +0 -125
  88. package/docs/components-notifications.zh.md +0 -125
  89. package/docs/components-user-management-user-center.ja.md +0 -148
  90. package/docs/components-user-management-user-center.md +0 -147
  91. package/docs/components-user-management-user-center.zh-TW.md +0 -148
  92. package/docs/components-user-management-user-center.zh.md +0 -148
  93. package/docs/components-user-management-user-sessions.ja.md +0 -121
  94. package/docs/components-user-management-user-sessions.md +0 -123
  95. package/docs/components-user-management-user-sessions.zh-TW.md +0 -121
  96. package/docs/components-user-management-user-sessions.zh.md +0 -121
  97. package/docs/components-user-management.ja.md +0 -49
  98. package/docs/components-user-management.md +0 -51
  99. package/docs/components-user-management.zh-TW.md +0 -49
  100. package/docs/components-user-management.zh.md +0 -49
  101. package/docs/components-utilities-icon.ja.md +0 -106
  102. package/docs/components-utilities-icon.md +0 -106
  103. package/docs/components-utilities-icon.zh-TW.md +0 -106
  104. package/docs/components-utilities-icon.zh.md +0 -106
  105. package/docs/components-utilities.ja.md +0 -136
  106. package/docs/components-utilities.md +0 -136
  107. package/docs/components-utilities.zh-TW.md +0 -136
  108. package/docs/components-utilities.zh.md +0 -136
  109. package/docs/components.ja.md +0 -27
  110. package/docs/components.md +0 -27
  111. package/docs/components.zh-TW.md +0 -27
  112. package/docs/components.zh.md +0 -27
  113. package/docs/core-concepts.ja.md +0 -134
  114. package/docs/core-concepts.md +0 -135
  115. package/docs/core-concepts.zh-TW.md +0 -134
  116. package/docs/core-concepts.zh.md +0 -134
  117. package/docs/getting-started.ja.md +0 -132
  118. package/docs/getting-started.md +0 -132
  119. package/docs/getting-started.zh-TW.md +0 -132
  120. package/docs/getting-started.zh.md +0 -132
  121. package/docs/hooks-api.ja.md +0 -214
  122. package/docs/hooks-api.md +0 -214
  123. package/docs/hooks-api.zh-TW.md +0 -214
  124. package/docs/hooks-api.zh.md +0 -214
  125. package/docs/how-to-guides.ja.md +0 -413
  126. package/docs/how-to-guides.md +0 -413
  127. package/docs/how-to-guides.zh-TW.md +0 -413
  128. package/docs/how-to-guides.zh.md +0 -413
  129. package/docs/overview.ja.md +0 -51
  130. package/docs/overview.md +0 -51
  131. package/docs/overview.zh-TW.md +0 -51
  132. package/docs/overview.zh.md +0 -51
  133. package/glossary.md +0 -12
  134. package/src/@types/index.ts +0 -230
  135. package/src/@types/shims.d.ts +0 -18
  136. package/src/BlockletStudio/README.md +0 -116
  137. package/src/BlockletStudio/index.tsx +0 -145
  138. package/src/ComponentInstaller/ComponentInstaller.stories.jsx +0 -16
  139. package/src/ComponentInstaller/index.jsx +0 -207
  140. package/src/ComponentInstaller/installer-item.jsx +0 -129
  141. package/src/ComponentInstaller/locales.js +0 -22
  142. package/src/ComponentInstaller/use-component-installed.js +0 -88
  143. package/src/ComponentManager/components/add-component.tsx +0 -136
  144. package/src/ComponentManager/components/check-component.tsx +0 -3
  145. package/src/ComponentManager/components/publish-component.tsx +0 -90
  146. package/src/ComponentManager/components/resource-dialog.tsx +0 -91
  147. package/src/ComponentManager/index.tsx +0 -3
  148. package/src/ComponentManager/libs/locales.ts +0 -15
  149. package/src/Dashboard/Dashboard.stories.jsx +0 -20
  150. package/src/Dashboard/app-shell/app-badge.stories.tsx +0 -64
  151. package/src/Dashboard/app-shell/app-badge.tsx +0 -94
  152. package/src/Dashboard/app-shell/app-header.tsx +0 -104
  153. package/src/Dashboard/app-shell/app-info-context.tsx +0 -182
  154. package/src/Dashboard/app-shell/badges/app-badge-default.tsx +0 -130
  155. package/src/Dashboard/app-shell/badges/app-badge-did.tsx +0 -28
  156. package/src/Dashboard/app-shell/badges/app-badge-state.tsx +0 -40
  157. package/src/Dashboard/app-shell/badges/app-badge-switch.tsx +0 -72
  158. package/src/Dashboard/app-shell/badges/app-badge-version.tsx +0 -60
  159. package/src/Dashboard/app-shell/index.ts +0 -5
  160. package/src/Dashboard/index.jsx +0 -184
  161. package/src/Footer/Footer.stories.jsx +0 -33
  162. package/src/Footer/brand.jsx +0 -81
  163. package/src/Footer/copyright.jsx +0 -22
  164. package/src/Footer/index.jsx +0 -111
  165. package/src/Footer/internal-footer.jsx +0 -139
  166. package/src/Footer/layout/plain.jsx +0 -55
  167. package/src/Footer/layout/row.jsx +0 -43
  168. package/src/Footer/layout/standard.jsx +0 -114
  169. package/src/Footer/links.jsx +0 -321
  170. package/src/Footer/social-media.jsx +0 -55
  171. package/src/Header/Header.stories.jsx +0 -30
  172. package/src/Header/index.tsx +0 -259
  173. package/src/Icon/Icon.stories.jsx +0 -12
  174. package/src/Icon/index.tsx +0 -87
  175. package/src/Notifications/Snackbar.tsx +0 -261
  176. package/src/Notifications/hooks/use-title.tsx +0 -254
  177. package/src/Notifications/hooks/use-width.tsx +0 -16
  178. package/src/Notifications/utils.ts +0 -246
  179. package/src/UserCenter/assets/banner.png +0 -0
  180. package/src/UserCenter/components/config-inviter.tsx +0 -48
  181. package/src/UserCenter/components/config-profile.tsx +0 -99
  182. package/src/UserCenter/components/danger-zone.tsx +0 -82
  183. package/src/UserCenter/components/editable-field.tsx +0 -273
  184. package/src/UserCenter/components/fallback.tsx +0 -57
  185. package/src/UserCenter/components/nft-preview.tsx +0 -84
  186. package/src/UserCenter/components/nft.tsx +0 -279
  187. package/src/UserCenter/components/notification.tsx +0 -319
  188. package/src/UserCenter/components/passport.tsx +0 -107
  189. package/src/UserCenter/components/privacy.tsx +0 -120
  190. package/src/UserCenter/components/settings.tsx +0 -170
  191. package/src/UserCenter/components/status-dialog/date-picker.tsx +0 -77
  192. package/src/UserCenter/components/status-dialog/index.tsx +0 -293
  193. package/src/UserCenter/components/status-selector/duration-menu.tsx +0 -90
  194. package/src/UserCenter/components/status-selector/index.tsx +0 -58
  195. package/src/UserCenter/components/status-selector/menu-item.tsx +0 -56
  196. package/src/UserCenter/components/storage/action.tsx +0 -49
  197. package/src/UserCenter/components/storage/connected.tsx +0 -61
  198. package/src/UserCenter/components/storage/delete.tsx +0 -72
  199. package/src/UserCenter/components/storage/disconnect.tsx +0 -40
  200. package/src/UserCenter/components/storage/icons/empty-spaces-nft.svg +0 -1
  201. package/src/UserCenter/components/storage/icons/long-arrow.svg +0 -5
  202. package/src/UserCenter/components/storage/icons/space-connected.svg +0 -3
  203. package/src/UserCenter/components/storage/icons/space-disconnect.svg +0 -3
  204. package/src/UserCenter/components/storage/index.tsx +0 -41
  205. package/src/UserCenter/components/storage/preview-nft.tsx +0 -72
  206. package/src/UserCenter/components/third-party-login/index.tsx +0 -199
  207. package/src/UserCenter/components/third-party-login/third-party-item.tsx +0 -296
  208. package/src/UserCenter/components/user-center.tsx +0 -787
  209. package/src/UserCenter/components/user-info/address.tsx +0 -143
  210. package/src/UserCenter/components/user-info/index.tsx +0 -4
  211. package/src/UserCenter/components/user-info/link-preview-input.tsx +0 -274
  212. package/src/UserCenter/components/user-info/metadata.tsx +0 -658
  213. package/src/UserCenter/components/user-info/social-actions/chat.tsx +0 -43
  214. package/src/UserCenter/components/user-info/social-actions/follow.tsx +0 -23
  215. package/src/UserCenter/components/user-info/social-actions/index.tsx +0 -17
  216. package/src/UserCenter/components/user-info/switch-role.tsx +0 -42
  217. package/src/UserCenter/components/user-info/timezone-select.tsx +0 -119
  218. package/src/UserCenter/components/user-info/user-basic-info.tsx +0 -292
  219. package/src/UserCenter/components/user-info/user-info-item.tsx +0 -54
  220. package/src/UserCenter/components/user-info/user-info.tsx +0 -91
  221. package/src/UserCenter/components/user-info/user-status.tsx +0 -234
  222. package/src/UserCenter/components/user-info/utils.ts +0 -320
  223. package/src/UserCenter/components/webhook-item.tsx +0 -248
  224. package/src/UserCenter/index.tsx +0 -1
  225. package/src/UserCenter/libs/locales.ts +0 -378
  226. package/src/UserCenter/libs/utils.ts +0 -30
  227. package/src/UserSessions/components/user-session-info.tsx +0 -78
  228. package/src/UserSessions/components/user-sessions.tsx +0 -545
  229. package/src/UserSessions/index.tsx +0 -1
  230. package/src/UserSessions/libs/locales.ts +0 -60
  231. package/src/UserSessions/libs/utils.ts +0 -82
  232. package/src/blocklets.js +0 -195
  233. package/src/common/domain-warning.jsx +0 -178
  234. package/src/common/header-addons.jsx +0 -119
  235. package/src/common/link-blocker.jsx +0 -20
  236. package/src/common/notification-addon.jsx +0 -135
  237. package/src/common/org-switch/avatar-uploader.jsx +0 -271
  238. package/src/common/org-switch/create.jsx +0 -267
  239. package/src/common/org-switch/index.jsx +0 -407
  240. package/src/common/org-switch/locales.js +0 -52
  241. package/src/common/org-switch/use-org.jsx +0 -79
  242. package/src/common/overridable-theme-provider.jsx +0 -17
  243. package/src/common/wallet-hidden-topbar.js +0 -14
  244. package/src/common/wizard-modal.jsx +0 -200
  245. package/src/common/ws.js +0 -68
  246. package/src/contexts/config-user-space.tsx +0 -88
  247. package/src/contexts/user-followers.tsx +0 -54
  248. package/src/hooks/use-follow.tsx +0 -75
  249. package/src/hooks/use-mobile.tsx +0 -6
  250. package/src/index.ts +0 -16
  251. package/src/libs/constant.ts +0 -1
  252. package/src/libs/spaces.tsx +0 -18
  253. package/src/libs/with-hide-when-embed.tsx +0 -24
  254. package/src/types.js +0 -45
  255. package/src/utils.js +0 -161
  256. package/vite.config.mjs +0 -34
@@ -1,87 +0,0 @@
1
- import 'iconify-icon';
2
- import { useState } from 'react';
3
- import { useAsyncEffect } from 'ahooks';
4
- import { Avatar } from '@mui/material';
5
- import type { AvatarProps, BoxProps } from '@mui/material';
6
- import { Icon as IconifyIcon, loadIcon } from '@iconify/react';
7
- import { isUrl } from '../utils';
8
-
9
- /**
10
- * Icon 组件, 基于 mui Avatar 组件扩展对 iconify 的支持
11
- */
12
- export default function Icon({
13
- icon,
14
- size = undefined,
15
- sx = {},
16
- ...rest
17
- }: {
18
- icon: string;
19
- size?: number;
20
- sx?: BoxProps['sx'];
21
- } & AvatarProps) {
22
- // eslint-disable-next-line @typescript-eslint/naming-convention
23
- const _sx = [...(Array.isArray(sx) ? sx : [sx])];
24
- if (size) {
25
- _sx.push({ width: size, height: size });
26
- }
27
- const [isIconify, setIsIconify] = useState(false);
28
- // NOTICE: 需要设置默认为 true,代表在判断 icon 是否为 iconify 时,需要等待 icon 加载完成
29
- const [loading, setLoading] = useState(true);
30
- useAsyncEffect(async () => {
31
- setLoading(true);
32
- try {
33
- await loadIcon(icon);
34
- setIsIconify(true);
35
- } catch {
36
- setIsIconify(false);
37
- }
38
- setLoading(false);
39
- }, [icon]);
40
- // 禁用默认的 circular variant 样式
41
- if (!rest.variant) {
42
- _sx.push({
43
- '&.MuiAvatar-root': {
44
- color: 'inherit',
45
- fontWeight: 'bold',
46
- backgroundColor: 'transparent',
47
- borderRadius: 0,
48
- },
49
- // 无 icon 背景时, svg icon 尺寸与窗口尺寸一致
50
- '&.MuiAvatar-root svg': {
51
- width: '100%',
52
- height: '100%',
53
- },
54
- });
55
- }
56
- if (isUrl(icon)) {
57
- return <Avatar component="span" {...rest} src={icon} sx={_sx} />;
58
- }
59
- // y = 0.6 * x + 4
60
- const height = size ? 0.6 * size + 4 : 0;
61
-
62
- if (loading) {
63
- return <IconifyIcon icon="codicon:blank" height={height || undefined} />;
64
- }
65
- if (isIconify) {
66
- return (
67
- <Avatar component="span" {...rest} sx={_sx}>
68
- <IconifyIcon icon={icon} height={height || undefined} />
69
- </Avatar>
70
- );
71
- }
72
- // letter avatar
73
- if (icon && typeof icon === 'string') {
74
- _sx.push({
75
- '&.MuiAvatar-root': {
76
- display: 'inline-flex',
77
- ...(size && { fontSize: size - 2 }),
78
- },
79
- });
80
- return (
81
- <Avatar component="span" {...rest} sx={_sx}>
82
- {Array.from(icon)[0]}
83
- </Avatar>
84
- );
85
- }
86
- return null;
87
- }
@@ -1,261 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
- import styled from '@emotion/styled';
3
-
4
- import { amber, green, common } from '@mui/material/colors';
5
- import { Box, IconButton, Typography } from '@mui/material';
6
- import { useCreation } from 'ahooks';
7
- import { Close as CloseIcon } from '@mui/icons-material';
8
- import { Icon, IconifyIcon } from '@iconify/react';
9
- import CheckIcon from '@iconify-icons/tabler/circle-check';
10
- import WarningIcon from '@iconify-icons/tabler/exclamation-circle';
11
- import InfoIcon from '@iconify-icons/tabler/info-circle';
12
- import ErrorIcon from '@iconify-icons/tabler/xbox-x';
13
-
14
- import { useSnackbar, SnackbarContent } from 'notistack';
15
-
16
- import useWidth from './hooks/use-width';
17
- import useActivityTitle from './hooks/use-title';
18
- import { isIncludeActivity, toClickableSpan, sanitize } from './utils';
19
-
20
- // Define type for breakpoints
21
- type BreakpointType = 'xl' | 'lg' | 'md' | 'sm';
22
-
23
- // Define types for notification component
24
-
25
- const variants: Record<string, IconifyIcon> = {
26
- normal: InfoIcon,
27
- success: CheckIcon,
28
- info: InfoIcon,
29
- warning: WarningIcon,
30
- error: ErrorIcon,
31
- };
32
-
33
- // Styled components
34
- const CloseIconStyled = styled(CloseIcon)`
35
- font-size: 20px;
36
- `;
37
-
38
- const MessageDiv = styled.div`
39
- display: flex;
40
- align-items: flex-start;
41
- gap: 8px;
42
- flex: 1;
43
- width: 0;
44
- `;
45
-
46
- const ActionDiv = styled.div`
47
- display: flex;
48
- align-items: center;
49
- margin-left: auto;
50
- margin-right: -8px;
51
- width: 44px;
52
- `;
53
-
54
- // Define breakpoints map
55
- const breakpointsMap: Record<BreakpointType, string> = {
56
- xl: '400px',
57
- lg: '400px',
58
- md: '400px',
59
- sm: '300px',
60
- };
61
-
62
- const StyledSnackbarContent = styled(SnackbarContent)<{ severity?: string; breakpoint: string }>`
63
- display: flex;
64
- color: #fff;
65
- align-items: center;
66
- padding: 12px 16px;
67
- border-radius: 4px;
68
- box-shadow:
69
- 0px 3px 5px -1px rgba(0, 0, 0, 0.2),
70
- 0px 6px 10px 0px rgba(0, 0, 0, 0.14),
71
- 0px 1px 18px 0px rgba(0, 0, 0, 0.12);
72
-
73
- ${({ severity, breakpoint }) => {
74
- const width = breakpointsMap[breakpoint as BreakpointType] || '400px';
75
-
76
- if (severity === 'success') {
77
- return `
78
- background-color: ${green[600]} !important;
79
- width: ${width};
80
- `;
81
- }
82
-
83
- if (severity === 'error') {
84
- return `
85
- background-color: #d32f2f !important;
86
- width: ${width};
87
- `;
88
- }
89
-
90
- if (severity === 'info') {
91
- return `
92
- background-color: #1976d2 !important;
93
- width: ${width};
94
- `;
95
- }
96
-
97
- if (severity === 'warning') {
98
- return `
99
- background-color: ${amber[700]} !important;
100
- width: ${width};
101
- `;
102
- }
103
-
104
- return `
105
- background-color: #333;
106
- width: ${width};
107
- `;
108
- }}
109
- `;
110
-
111
- const ClickableDiv = styled.div`
112
- cursor: pointer;
113
- display: flex;
114
- flex-direction: column;
115
- .title {
116
- overflow: hidden;
117
- text-overflow: ellipsis;
118
- display: -webkit-box;
119
- -webkit-line-clamp: 1;
120
- -webkit-box-orient: vertical;
121
- font-weight: bold;
122
- }
123
- .desc {
124
- overflow: hidden;
125
- text-overflow: ellipsis;
126
- display: -webkit-box;
127
- -webkit-line-clamp: 3;
128
- -webkit-box-orient: vertical;
129
- word-break: break-word;
130
- line-height: 1.2;
131
- .link,
132
- .dapp,
133
- .common {
134
- color: ${common.white};
135
- }
136
- }
137
- `;
138
-
139
- interface NotificationComponentProps {
140
- viewAllUrl: string;
141
- keyId: number;
142
- notification?: {
143
- severity?: string;
144
- title?: string;
145
- description?: string;
146
- activity?: any;
147
- actorInfo?: any;
148
- };
149
- // eslint-disable-next-line react/require-default-props
150
- content?: React.ReactNode;
151
- }
152
-
153
- export default function NotificationComponent({
154
- ref = undefined,
155
- keyId: key,
156
- notification = {},
157
- viewAllUrl,
158
- content = null,
159
- }: NotificationComponentProps & {
160
- ref?: React.Ref<unknown>;
161
- }) {
162
- const breakpoint = useWidth();
163
- const [description, setDescription] = useState(notification.description || '');
164
- const icon = variants[notification.severity || ''];
165
-
166
- const { closeSnackbar } = useSnackbar();
167
- const onClickDismiss = () => closeSnackbar(key);
168
-
169
- useEffect(() => {
170
- toClickableSpan(notification.description || '', 'en').then((res) => {
171
- setDescription(res);
172
- });
173
- }, [notification.description]);
174
-
175
- const onGoNotification = (e: any) => {
176
- e.stopPropagation();
177
- closeSnackbar(key);
178
-
179
- // 已确认 viewAllUrl都是本地的相对地址
180
- if (!e?.customPreventRedirect) {
181
- window.open(viewAllUrl, '_blank');
182
- }
183
- };
184
-
185
- const includeActivity = useCreation(() => {
186
- return isIncludeActivity(notification);
187
- }, [notification]);
188
- const activity = useCreation(() => {
189
- return notification?.activity;
190
- }, [notification]);
191
-
192
- const activityMeta = useCreation(() => {
193
- if (!activity || activity.type === 'tips') {
194
- return null;
195
- }
196
-
197
- return activity?.meta;
198
- }, [activity]);
199
-
200
- const activityTitle = useActivityTitle({
201
- activity,
202
- users: [notification?.actorInfo],
203
- actors: [notification?.activity?.actor],
204
- extra: {
205
- linkColor: common.white,
206
- },
207
- });
208
-
209
- return (
210
- <StyledSnackbarContent
211
- ref={ref as React.Ref<HTMLDivElement>}
212
- severity={notification.severity}
213
- breakpoint={breakpoint}>
214
- <MessageDiv>
215
- {icon ? <Icon icon={icon} fontSize={24} /> : null}
216
- <ClickableDiv onClick={onGoNotification} style={{ width: 'calc(100% - 30px)' }}>
217
- <Box>
218
- {includeActivity ? (
219
- <>
220
- <span className="title">{activityTitle}</span>
221
- {activityMeta ? (
222
- <Typography
223
- variant="subtitle2"
224
- component="p"
225
- sx={{
226
- fontSize: 16,
227
- display: '-webkit-box',
228
- overflow: 'hidden',
229
- textOverflow: 'ellipsis',
230
- WebkitLineClamp: 3,
231
- WebkitBoxOrient: 'vertical',
232
- color: common.white,
233
- lineHeight: 1.2,
234
- }}>
235
- {activityMeta?.content}
236
- </Typography>
237
- ) : null}
238
- </>
239
- ) : (
240
- <>
241
- <span className="title">{notification.title}</span>
242
- {content || (
243
- <Typography
244
- component="span"
245
- className="desc"
246
- dangerouslySetInnerHTML={{ __html: sanitize(description) }}
247
- />
248
- )}
249
- </>
250
- )}
251
- </Box>
252
- </ClickableDiv>
253
- </MessageDiv>
254
- <ActionDiv>
255
- <IconButton key="close" aria-label="close" color="inherit" onClick={onClickDismiss} size="large">
256
- <CloseIconStyled />
257
- </IconButton>
258
- </ActionDiv>
259
- </StyledSnackbarContent>
260
- );
261
- }
@@ -1,254 +0,0 @@
1
- /* eslint-disable react/prop-types */
2
- import React, { MouseEvent } from 'react';
3
- import { useCreation, useMemoizedFn } from 'ahooks';
4
- import { useTheme, Link } from '@mui/material';
5
- import { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
6
- import { joinURL, withQuery } from 'ufo';
7
- import isEmpty from 'lodash/isEmpty';
8
- import { getActivityLink } from '../utils';
9
-
10
- /**
11
- * Activity types enum for type safety
12
- * @readonly
13
- * @enum {string}
14
- */
15
- const ACTIVITY_TYPES = {
16
- COMMENT: 'comment',
17
- LIKE: 'like',
18
- FOLLOW: 'follow',
19
- TIPS: 'tips',
20
- MENTION: 'mention',
21
- ASSIGN: 'assign',
22
- } as const;
23
-
24
- type ActivityTypeValues = (typeof ACTIVITY_TYPES)[keyof typeof ACTIVITY_TYPES];
25
-
26
- /**
27
- * Activity descriptions mapping
28
- * @type {Object.<string, React.ReactNode>}
29
- */
30
- const ACTIVITY_DESCRIPTIONS: Record<ActivityTypeValues, (targetType: string, count?: number) => React.ReactNode> = {
31
- comment: (targetType: string, count?: number) =>
32
- count && count > 1 ? (
33
- <>
34
- left {count} comments on your {targetType}
35
- </>
36
- ) : (
37
- <>commented on your {targetType}</>
38
- ),
39
- like: (targetType: string) => <>liked your {targetType}</>,
40
- follow: () => <>followed you</>,
41
- tips: (targetType: string) => <>gave tips to your {targetType}</>,
42
- mention: (targetType: string) => <>mentioned you in {targetType}</>,
43
- assign: () => <>assigned you a task</>,
44
- };
45
-
46
- interface UserData {
47
- did: string;
48
- fullName: string;
49
- }
50
-
51
- interface UserLinkProps {
52
- user: UserData;
53
- color?: string;
54
- }
55
-
56
- interface CustomMouseEvent extends MouseEvent<HTMLAnchorElement> {
57
- customPreventRedirect?: boolean;
58
- }
59
-
60
- /**
61
- * UserLink component for rendering a user's name as a profile link
62
- * Memoized to prevent unnecessary re-renders
63
- */
64
- function UserLink({ user, color = undefined }: UserLinkProps) {
65
- const { palette } = useTheme();
66
- const profileLink = withQuery(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, 'user'), { did: user.did });
67
- // eslint-disable-next-line @typescript-eslint/naming-convention
68
- const _color = color || palette.text.primary;
69
-
70
- return (
71
- <Link
72
- href={profileLink}
73
- color={_color}
74
- target="_blank"
75
- onClick={(e: CustomMouseEvent) => {
76
- e.customPreventRedirect = true;
77
- }}
78
- sx={{
79
- fontWeight: 600,
80
- textDecoration: 'none',
81
- '&:hover': { cursor: 'pointer' },
82
- }}>
83
- {user.fullName || 'System'}
84
- </Link>
85
- );
86
- }
87
-
88
- UserLink.displayName = 'UserLink';
89
-
90
- interface ActivityTarget {
91
- type: string;
92
- name: string;
93
- }
94
-
95
- interface Activity {
96
- type: ActivityTypeValues;
97
- target: ActivityTarget;
98
- }
99
-
100
- interface ExtraParams {
101
- linkColor?: string;
102
- [key: string]: any;
103
- }
104
-
105
- interface ActivityTitleProps {
106
- activity: Activity;
107
- users: UserData[];
108
- actors: string[];
109
- extra?: ExtraParams;
110
- mountPoint?: string;
111
- }
112
-
113
- /**
114
- * A hook that returns a formatted activity title with linked usernames
115
- * @param {Object} params - The parameters object
116
- * @param {keyof typeof ACTIVITY_TYPES} params.type - The activity type
117
- * @param {Object} params.target - The target object
118
- * @param {Array<{did: string, fullName: string}>} params.users - Array of user objects
119
- * @param {Object} params.extra - Extra parameters
120
- * @returns {React.ReactNode} Formatted title with linked usernames
121
- */
122
- export default function useActivityTitle({ activity, users, actors, extra = {}, mountPoint = '' }: ActivityTitleProps) {
123
- const { palette } = useTheme();
124
- const { type, target } = activity || {};
125
- const { type: targetType } = target || {};
126
- const { linkColor = palette.text.primary } = extra || {};
127
-
128
- // Create a map of users by their DID for efficient lookup
129
- const usersMap = useCreation(() => {
130
- if (!Array.isArray(users)) return new Map<string, UserData>();
131
- const map = new Map<string, UserData>();
132
- users.forEach((user) => {
133
- if (user?.did && !map.has(user.did)) {
134
- map.set(user.did, user);
135
- }
136
- });
137
- return map;
138
- }, [users]);
139
-
140
- // Get unique users from actors, using the map and providing fallback for missing users
141
- const uniqueUsers = useCreation(() => {
142
- if (!Array.isArray(actors)) return [];
143
-
144
- return actors
145
- .map((actorId) => {
146
- if (!actorId) return null;
147
- // If user exists in map, return the user object, otherwise create a basic object with DID
148
- return usersMap.get(actorId) || { did: actorId, fullName: 'System' };
149
- })
150
- .filter(Boolean) as UserData[];
151
- }, [actors, usersMap]);
152
-
153
- // Memoized function to format user names with links
154
- const formatLinkedUserNames = useMemoizedFn(() => {
155
- if (!Array.isArray(uniqueUsers) || uniqueUsers.length === 0) {
156
- return null;
157
- }
158
-
159
- // Early return for single user case
160
- if (uniqueUsers.length === 1) {
161
- return <UserLink user={uniqueUsers[0]} color={linkColor} />;
162
- }
163
-
164
- // Get all users except the last one for multi-user cases
165
- const initialUsers = uniqueUsers.slice(0, -1);
166
- const lastUser = uniqueUsers[uniqueUsers.length - 1];
167
-
168
- // Early return for two users case
169
- if (uniqueUsers.length === 2) {
170
- return (
171
- <>
172
- <UserLink user={initialUsers[0]} color={linkColor} />
173
- {' and '}
174
- <UserLink user={lastUser} color={linkColor} />
175
- </>
176
- );
177
- }
178
-
179
- // Handle three or more users
180
- const isMoreThanThree = uniqueUsers.length > 3;
181
- const displayUsers = isMoreThanThree ? uniqueUsers.slice(0, 2) : initialUsers;
182
-
183
- return (
184
- <>
185
- {displayUsers.map((user, index) => (
186
- <React.Fragment key={user.did}>
187
- <UserLink user={user} color={linkColor} />
188
- {index < displayUsers.length - 1 ? ', ' : ''}
189
- </React.Fragment>
190
- ))}
191
- {isMoreThanThree ? (
192
- `, and ${uniqueUsers.length - 2} others`
193
- ) : (
194
- <>
195
- , and <UserLink user={lastUser} color={linkColor} />
196
- </>
197
- )}
198
- </>
199
- );
200
- });
201
-
202
- // Memoized function to get activity description
203
- const getActivityDescription = useMemoizedFn(() => {
204
- const descriptionFn = type ? ACTIVITY_DESCRIPTIONS[type] : null;
205
- return descriptionFn ? descriptionFn(targetType, users.length) : null;
206
- });
207
-
208
- // Create the final title using memoization
209
- const title = useCreation(() => {
210
- const linkedNames = formatLinkedUserNames();
211
- const description = getActivityDescription();
212
-
213
- if (!linkedNames || !description) {
214
- return null;
215
- }
216
-
217
- return (
218
- <>
219
- {linkedNames} {description}
220
- </>
221
- );
222
- }, [type, targetType, uniqueUsers, formatLinkedUserNames, getActivityDescription]);
223
-
224
- const targetLink = useCreation(() => {
225
- if (!activity) return null;
226
- const link = getActivityLink(activity);
227
- if (link?.targetLink) {
228
- return joinURL(mountPoint, link.targetLink);
229
- }
230
- return null;
231
- }, [activity, mountPoint]);
232
-
233
- if (!type || isEmpty(target)) {
234
- return null;
235
- }
236
-
237
- return (
238
- <>
239
- {title}{' '}
240
- {targetLink && (
241
- <Link
242
- href={targetLink}
243
- color={linkColor}
244
- target="_blank"
245
- sx={{ textDecoration: 'none' }}
246
- onClick={(e: CustomMouseEvent) => {
247
- e.customPreventRedirect = true;
248
- }}>
249
- {target.name}
250
- </Link>
251
- )}
252
- </>
253
- );
254
- }
@@ -1,16 +0,0 @@
1
- import { useTheme } from '@arcblock/ux/lib/Theme';
2
- import { useMediaQuery } from '@mui/material';
3
-
4
- function useWidth() {
5
- const theme = useTheme();
6
- const keys = [...theme.breakpoints.keys].reverse();
7
- return (
8
- keys.reduce<string | null>((output, key) => {
9
- // eslint-disable-next-line
10
- const matches = useMediaQuery(theme.breakpoints.up(key));
11
- return !output && matches ? key : output;
12
- }, null) || 'xs'
13
- );
14
- }
15
-
16
- export default useWidth;