@blocklet/ui-react 3.4.15 → 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 (255) hide show
  1. package/lib/common/org-switch/use-org.d.ts +4 -4
  2. package/package.json +9 -6
  3. package/.aigne/doc-smith/.local/afs-storage.sqlite3 +0 -0
  4. package/.aigne/doc-smith/config.yaml +0 -78
  5. package/.aigne/doc-smith/history.yaml +0 -14
  6. package/.aigne/doc-smith/media-description.yaml +0 -11
  7. package/.aigne/doc-smith/output/structure-plan.json +0 -255
  8. package/.aigne/doc-smith/translation-cache.yaml +0 -11
  9. package/.aigne/doc-smith/upload-cache.yaml +0 -528
  10. package/build.config.ts +0 -24
  11. package/docs/_sidebar.md +0 -19
  12. package/docs/assets/diagram/component-installer-diagram-0.ja.jpg +0 -0
  13. package/docs/assets/diagram/component-installer-diagram-0.jpg +0 -0
  14. package/docs/assets/diagram/component-installer-diagram-0.zh-TW.jpg +0 -0
  15. package/docs/assets/diagram/component-installer-diagram-0.zh.jpg +0 -0
  16. package/docs/assets/diagram/component-management-diagram-0.ja.jpg +0 -0
  17. package/docs/assets/diagram/component-management-diagram-0.jpg +0 -0
  18. package/docs/assets/diagram/component-management-diagram-0.zh-TW.jpg +0 -0
  19. package/docs/assets/diagram/component-management-diagram-0.zh.jpg +0 -0
  20. package/docs/assets/diagram/core-concepts-diagram-0.ja.jpg +0 -0
  21. package/docs/assets/diagram/core-concepts-diagram-0.jpg +0 -0
  22. package/docs/assets/diagram/core-concepts-diagram-0.zh-TW.jpg +0 -0
  23. package/docs/assets/diagram/core-concepts-diagram-0.zh.jpg +0 -0
  24. package/docs/assets/diagram/dashboard-diagram-0.ja.jpg +0 -0
  25. package/docs/assets/diagram/dashboard-diagram-0.jpg +0 -0
  26. package/docs/assets/diagram/dashboard-diagram-0.zh-TW.jpg +0 -0
  27. package/docs/assets/diagram/dashboard-diagram-0.zh.jpg +0 -0
  28. package/docs/assets/diagram/header-diagram-0.ja.jpg +0 -0
  29. package/docs/assets/diagram/header-diagram-0.jpg +0 -0
  30. package/docs/assets/diagram/header-diagram-0.zh-TW.jpg +0 -0
  31. package/docs/assets/diagram/header-diagram-0.zh.jpg +0 -0
  32. package/docs/assets/diagram/layout-diagram-0.ja.jpg +0 -0
  33. package/docs/assets/diagram/layout-diagram-0.jpg +0 -0
  34. package/docs/assets/diagram/layout-diagram-0.zh-TW.jpg +0 -0
  35. package/docs/assets/diagram/layout-diagram-0.zh.jpg +0 -0
  36. package/docs/assets/diagram/notifications-diagram-0.ja.jpg +0 -0
  37. package/docs/assets/diagram/notifications-diagram-0.jpg +0 -0
  38. package/docs/assets/diagram/notifications-diagram-0.zh-TW.jpg +0 -0
  39. package/docs/assets/diagram/notifications-diagram-0.zh.jpg +0 -0
  40. package/docs/assets/diagram/overview-diagram-0.ja.jpg +0 -0
  41. package/docs/assets/diagram/overview-diagram-0.jpg +0 -0
  42. package/docs/assets/diagram/overview-diagram-0.zh-TW.jpg +0 -0
  43. package/docs/assets/diagram/overview-diagram-0.zh.jpg +0 -0
  44. package/docs/assets/diagram/user-center-diagram-0.ja.jpg +0 -0
  45. package/docs/assets/diagram/user-center-diagram-0.jpg +0 -0
  46. package/docs/assets/diagram/user-center-diagram-0.zh-TW.jpg +0 -0
  47. package/docs/assets/diagram/user-center-diagram-0.zh.jpg +0 -0
  48. package/docs/assets/diagram/user-management-diagram-0.ja.jpg +0 -0
  49. package/docs/assets/diagram/user-management-diagram-0.jpg +0 -0
  50. package/docs/assets/diagram/user-management-diagram-0.zh-TW.jpg +0 -0
  51. package/docs/assets/diagram/user-management-diagram-0.zh.jpg +0 -0
  52. package/docs/assets/diagram/user-sessions-diagram-0.ja.jpg +0 -0
  53. package/docs/assets/diagram/user-sessions-diagram-0.jpg +0 -0
  54. package/docs/assets/diagram/user-sessions-diagram-0.zh-TW.jpg +0 -0
  55. package/docs/assets/diagram/user-sessions-diagram-0.zh.jpg +0 -0
  56. package/docs/components-component-management-blocklet-studio.ja.md +0 -194
  57. package/docs/components-component-management-blocklet-studio.md +0 -194
  58. package/docs/components-component-management-blocklet-studio.zh-TW.md +0 -194
  59. package/docs/components-component-management-blocklet-studio.zh.md +0 -194
  60. package/docs/components-component-management-component-installer.ja.md +0 -182
  61. package/docs/components-component-management-component-installer.md +0 -182
  62. package/docs/components-component-management-component-installer.zh-TW.md +0 -182
  63. package/docs/components-component-management-component-installer.zh.md +0 -182
  64. package/docs/components-component-management.ja.md +0 -30
  65. package/docs/components-component-management.md +0 -30
  66. package/docs/components-component-management.zh-TW.md +0 -30
  67. package/docs/components-component-management.zh.md +0 -30
  68. package/docs/components-layout-dashboard.ja.md +0 -185
  69. package/docs/components-layout-dashboard.md +0 -187
  70. package/docs/components-layout-dashboard.zh-TW.md +0 -185
  71. package/docs/components-layout-dashboard.zh.md +0 -185
  72. package/docs/components-layout-footer.ja.md +0 -165
  73. package/docs/components-layout-footer.md +0 -165
  74. package/docs/components-layout-footer.zh-TW.md +0 -165
  75. package/docs/components-layout-footer.zh.md +0 -165
  76. package/docs/components-layout-header.ja.md +0 -183
  77. package/docs/components-layout-header.md +0 -183
  78. package/docs/components-layout-header.zh-TW.md +0 -183
  79. package/docs/components-layout-header.zh.md +0 -183
  80. package/docs/components-layout.ja.md +0 -31
  81. package/docs/components-layout.md +0 -31
  82. package/docs/components-layout.zh-TW.md +0 -31
  83. package/docs/components-layout.zh.md +0 -31
  84. package/docs/components-notifications.ja.md +0 -125
  85. package/docs/components-notifications.md +0 -125
  86. package/docs/components-notifications.zh-TW.md +0 -125
  87. package/docs/components-notifications.zh.md +0 -125
  88. package/docs/components-user-management-user-center.ja.md +0 -148
  89. package/docs/components-user-management-user-center.md +0 -147
  90. package/docs/components-user-management-user-center.zh-TW.md +0 -148
  91. package/docs/components-user-management-user-center.zh.md +0 -148
  92. package/docs/components-user-management-user-sessions.ja.md +0 -121
  93. package/docs/components-user-management-user-sessions.md +0 -123
  94. package/docs/components-user-management-user-sessions.zh-TW.md +0 -121
  95. package/docs/components-user-management-user-sessions.zh.md +0 -121
  96. package/docs/components-user-management.ja.md +0 -49
  97. package/docs/components-user-management.md +0 -51
  98. package/docs/components-user-management.zh-TW.md +0 -49
  99. package/docs/components-user-management.zh.md +0 -49
  100. package/docs/components-utilities-icon.ja.md +0 -106
  101. package/docs/components-utilities-icon.md +0 -106
  102. package/docs/components-utilities-icon.zh-TW.md +0 -106
  103. package/docs/components-utilities-icon.zh.md +0 -106
  104. package/docs/components-utilities.ja.md +0 -136
  105. package/docs/components-utilities.md +0 -136
  106. package/docs/components-utilities.zh-TW.md +0 -136
  107. package/docs/components-utilities.zh.md +0 -136
  108. package/docs/components.ja.md +0 -27
  109. package/docs/components.md +0 -27
  110. package/docs/components.zh-TW.md +0 -27
  111. package/docs/components.zh.md +0 -27
  112. package/docs/core-concepts.ja.md +0 -134
  113. package/docs/core-concepts.md +0 -135
  114. package/docs/core-concepts.zh-TW.md +0 -134
  115. package/docs/core-concepts.zh.md +0 -134
  116. package/docs/getting-started.ja.md +0 -132
  117. package/docs/getting-started.md +0 -132
  118. package/docs/getting-started.zh-TW.md +0 -132
  119. package/docs/getting-started.zh.md +0 -132
  120. package/docs/hooks-api.ja.md +0 -214
  121. package/docs/hooks-api.md +0 -214
  122. package/docs/hooks-api.zh-TW.md +0 -214
  123. package/docs/hooks-api.zh.md +0 -214
  124. package/docs/how-to-guides.ja.md +0 -413
  125. package/docs/how-to-guides.md +0 -413
  126. package/docs/how-to-guides.zh-TW.md +0 -413
  127. package/docs/how-to-guides.zh.md +0 -413
  128. package/docs/overview.ja.md +0 -51
  129. package/docs/overview.md +0 -51
  130. package/docs/overview.zh-TW.md +0 -51
  131. package/docs/overview.zh.md +0 -51
  132. package/glossary.md +0 -12
  133. package/src/@types/index.ts +0 -230
  134. package/src/@types/shims.d.ts +0 -18
  135. package/src/BlockletStudio/README.md +0 -116
  136. package/src/BlockletStudio/index.tsx +0 -145
  137. package/src/ComponentInstaller/ComponentInstaller.stories.jsx +0 -16
  138. package/src/ComponentInstaller/index.jsx +0 -207
  139. package/src/ComponentInstaller/installer-item.jsx +0 -129
  140. package/src/ComponentInstaller/locales.js +0 -22
  141. package/src/ComponentInstaller/use-component-installed.js +0 -88
  142. package/src/ComponentManager/components/add-component.tsx +0 -136
  143. package/src/ComponentManager/components/check-component.tsx +0 -3
  144. package/src/ComponentManager/components/publish-component.tsx +0 -90
  145. package/src/ComponentManager/components/resource-dialog.tsx +0 -91
  146. package/src/ComponentManager/index.tsx +0 -3
  147. package/src/ComponentManager/libs/locales.ts +0 -15
  148. package/src/Dashboard/Dashboard.stories.jsx +0 -20
  149. package/src/Dashboard/app-shell/app-badge.stories.tsx +0 -64
  150. package/src/Dashboard/app-shell/app-badge.tsx +0 -94
  151. package/src/Dashboard/app-shell/app-header.tsx +0 -104
  152. package/src/Dashboard/app-shell/app-info-context.tsx +0 -182
  153. package/src/Dashboard/app-shell/badges/app-badge-default.tsx +0 -130
  154. package/src/Dashboard/app-shell/badges/app-badge-did.tsx +0 -28
  155. package/src/Dashboard/app-shell/badges/app-badge-state.tsx +0 -40
  156. package/src/Dashboard/app-shell/badges/app-badge-switch.tsx +0 -72
  157. package/src/Dashboard/app-shell/badges/app-badge-version.tsx +0 -60
  158. package/src/Dashboard/app-shell/index.ts +0 -5
  159. package/src/Dashboard/index.jsx +0 -184
  160. package/src/Footer/Footer.stories.jsx +0 -33
  161. package/src/Footer/brand.jsx +0 -81
  162. package/src/Footer/copyright.jsx +0 -22
  163. package/src/Footer/index.jsx +0 -111
  164. package/src/Footer/internal-footer.jsx +0 -139
  165. package/src/Footer/layout/plain.jsx +0 -55
  166. package/src/Footer/layout/row.jsx +0 -43
  167. package/src/Footer/layout/standard.jsx +0 -114
  168. package/src/Footer/links.jsx +0 -321
  169. package/src/Footer/social-media.jsx +0 -55
  170. package/src/Header/Header.stories.jsx +0 -30
  171. package/src/Header/index.tsx +0 -259
  172. package/src/Icon/Icon.stories.jsx +0 -12
  173. package/src/Icon/index.tsx +0 -87
  174. package/src/Notifications/Snackbar.tsx +0 -261
  175. package/src/Notifications/hooks/use-title.tsx +0 -254
  176. package/src/Notifications/hooks/use-width.tsx +0 -16
  177. package/src/Notifications/utils.ts +0 -246
  178. package/src/UserCenter/assets/banner.png +0 -0
  179. package/src/UserCenter/components/config-inviter.tsx +0 -48
  180. package/src/UserCenter/components/config-profile.tsx +0 -99
  181. package/src/UserCenter/components/danger-zone.tsx +0 -82
  182. package/src/UserCenter/components/editable-field.tsx +0 -273
  183. package/src/UserCenter/components/fallback.tsx +0 -57
  184. package/src/UserCenter/components/nft-preview.tsx +0 -84
  185. package/src/UserCenter/components/nft.tsx +0 -279
  186. package/src/UserCenter/components/notification.tsx +0 -319
  187. package/src/UserCenter/components/passport.tsx +0 -107
  188. package/src/UserCenter/components/privacy.tsx +0 -120
  189. package/src/UserCenter/components/settings.tsx +0 -170
  190. package/src/UserCenter/components/status-dialog/date-picker.tsx +0 -77
  191. package/src/UserCenter/components/status-dialog/index.tsx +0 -293
  192. package/src/UserCenter/components/status-selector/duration-menu.tsx +0 -90
  193. package/src/UserCenter/components/status-selector/index.tsx +0 -58
  194. package/src/UserCenter/components/status-selector/menu-item.tsx +0 -56
  195. package/src/UserCenter/components/storage/action.tsx +0 -49
  196. package/src/UserCenter/components/storage/connected.tsx +0 -61
  197. package/src/UserCenter/components/storage/delete.tsx +0 -72
  198. package/src/UserCenter/components/storage/disconnect.tsx +0 -40
  199. package/src/UserCenter/components/storage/icons/empty-spaces-nft.svg +0 -1
  200. package/src/UserCenter/components/storage/icons/long-arrow.svg +0 -5
  201. package/src/UserCenter/components/storage/icons/space-connected.svg +0 -3
  202. package/src/UserCenter/components/storage/icons/space-disconnect.svg +0 -3
  203. package/src/UserCenter/components/storage/index.tsx +0 -41
  204. package/src/UserCenter/components/storage/preview-nft.tsx +0 -72
  205. package/src/UserCenter/components/third-party-login/index.tsx +0 -199
  206. package/src/UserCenter/components/third-party-login/third-party-item.tsx +0 -296
  207. package/src/UserCenter/components/user-center.tsx +0 -787
  208. package/src/UserCenter/components/user-info/address.tsx +0 -143
  209. package/src/UserCenter/components/user-info/index.tsx +0 -4
  210. package/src/UserCenter/components/user-info/link-preview-input.tsx +0 -274
  211. package/src/UserCenter/components/user-info/metadata.tsx +0 -658
  212. package/src/UserCenter/components/user-info/social-actions/chat.tsx +0 -43
  213. package/src/UserCenter/components/user-info/social-actions/follow.tsx +0 -23
  214. package/src/UserCenter/components/user-info/social-actions/index.tsx +0 -17
  215. package/src/UserCenter/components/user-info/switch-role.tsx +0 -42
  216. package/src/UserCenter/components/user-info/timezone-select.tsx +0 -119
  217. package/src/UserCenter/components/user-info/user-basic-info.tsx +0 -292
  218. package/src/UserCenter/components/user-info/user-info-item.tsx +0 -54
  219. package/src/UserCenter/components/user-info/user-info.tsx +0 -91
  220. package/src/UserCenter/components/user-info/user-status.tsx +0 -234
  221. package/src/UserCenter/components/user-info/utils.ts +0 -320
  222. package/src/UserCenter/components/webhook-item.tsx +0 -248
  223. package/src/UserCenter/index.tsx +0 -1
  224. package/src/UserCenter/libs/locales.ts +0 -378
  225. package/src/UserCenter/libs/utils.ts +0 -30
  226. package/src/UserSessions/components/user-session-info.tsx +0 -78
  227. package/src/UserSessions/components/user-sessions.tsx +0 -545
  228. package/src/UserSessions/index.tsx +0 -1
  229. package/src/UserSessions/libs/locales.ts +0 -60
  230. package/src/UserSessions/libs/utils.ts +0 -82
  231. package/src/blocklets.js +0 -195
  232. package/src/common/domain-warning.jsx +0 -178
  233. package/src/common/header-addons.jsx +0 -119
  234. package/src/common/link-blocker.jsx +0 -20
  235. package/src/common/notification-addon.jsx +0 -135
  236. package/src/common/org-switch/avatar-uploader.jsx +0 -271
  237. package/src/common/org-switch/create.jsx +0 -267
  238. package/src/common/org-switch/index.jsx +0 -407
  239. package/src/common/org-switch/locales.js +0 -52
  240. package/src/common/org-switch/use-org.jsx +0 -79
  241. package/src/common/overridable-theme-provider.jsx +0 -17
  242. package/src/common/wallet-hidden-topbar.js +0 -14
  243. package/src/common/wizard-modal.jsx +0 -200
  244. package/src/common/ws.js +0 -68
  245. package/src/contexts/config-user-space.tsx +0 -88
  246. package/src/contexts/user-followers.tsx +0 -54
  247. package/src/hooks/use-follow.tsx +0 -75
  248. package/src/hooks/use-mobile.tsx +0 -6
  249. package/src/index.ts +0 -16
  250. package/src/libs/constant.ts +0 -1
  251. package/src/libs/spaces.tsx +0 -18
  252. package/src/libs/with-hide-when-embed.tsx +0 -24
  253. package/src/types.js +0 -45
  254. package/src/utils.js +0 -161
  255. package/vite.config.mjs +0 -34
@@ -1,273 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { useCreation, useMemoizedFn } from 'ahooks';
3
- import { Box, TextField, Typography, Tooltip, type TooltipProps, useTheme } from '@mui/material';
4
- import { Verified as VerifiedIcon } from '@mui/icons-material';
5
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
6
- import { translate } from '@arcblock/ux/lib/Locale/util';
7
- import { mergeSx } from '@arcblock/ux/lib/Util/style';
8
- import { translations } from '../libs/locales';
9
-
10
- interface EditableFieldProps {
11
- value: string;
12
- onChange?: (value: string) => void;
13
- onValueValidate?: (value: string) => void;
14
- editable?: boolean;
15
- disabled?: boolean;
16
- component?: 'input' | 'textarea';
17
- placeholder?: string;
18
- rows?: number;
19
- maxLength?: number; // 最大字符数
20
- icon?: React.ReactNode;
21
- label?: string | React.ReactNode;
22
- children?: React.ReactNode;
23
- tooltip?: TooltipProps['title'];
24
- inline?: boolean;
25
- style?: React.CSSProperties;
26
- verified?: boolean;
27
- errorMsg?: string;
28
- canEdit?: boolean;
29
- hidePreview?: boolean;
30
- renderValue?: (value: string) => React.ReactNode;
31
- }
32
-
33
- /** only for sx */
34
- export const commonInputStyle = {
35
- '.MuiOutlinedInput-root': {
36
- '&:hover': {
37
- fieldset: {
38
- borderColor: 'divider',
39
- },
40
- },
41
- '&.Mui-focused': {
42
- fieldset: {
43
- borderColor: 'divider',
44
- },
45
- },
46
- },
47
- };
48
-
49
- /** only for sx */
50
- export const inputFieldStyle = {
51
- width: '100%',
52
- '& .MuiFormHelperText-root': {
53
- position: 'relative',
54
- bottom: 0,
55
- left: 0,
56
- margin: 0,
57
- },
58
- fieldset: {
59
- borderColor: 'divider',
60
- },
61
- };
62
-
63
- function EditableField({
64
- value,
65
- onChange = () => {},
66
- onValueValidate = () => {},
67
- errorMsg = '',
68
- editable = false,
69
- component = 'input',
70
- placeholder = '',
71
- rows = 2,
72
- maxLength = undefined,
73
- icon = undefined,
74
- label = '',
75
- children = undefined,
76
- tooltip = undefined,
77
- inline = true,
78
- style = {},
79
- verified = false,
80
- canEdit = true,
81
- renderValue = undefined,
82
- disabled = false,
83
- hidePreview = false,
84
- }: EditableFieldProps) {
85
- const { locale } = useLocaleContext();
86
- const theme = useTheme();
87
- const isDark = theme.palette.mode === 'dark';
88
- const t = useMemoizedFn((key, data = {}) => {
89
- return translate(translations, key, locale, 'en', data);
90
- });
91
-
92
- // 存储鼠标位置的状态
93
- const [mousePosition, setMousePosition] = useState<{
94
- mouseX: number;
95
- mouseY: number;
96
- } | null>(null);
97
-
98
- // 处理鼠标移动事件,更新鼠标位置
99
- const handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {
100
- setMousePosition({
101
- mouseX: event.clientX,
102
- mouseY: event.clientY,
103
- });
104
- };
105
-
106
- // 处理鼠标离开事件,清除鼠标位置
107
- const handleMouseLeave = () => {
108
- setMousePosition(null);
109
- };
110
-
111
- const handleChange = useMemoizedFn((v: string) => {
112
- if (onChange) {
113
- onChange(v);
114
- }
115
- if (onValueValidate) {
116
- onValueValidate(v);
117
- }
118
- });
119
-
120
- const content = useCreation(() => {
121
- if (children) {
122
- return children;
123
- }
124
- if (component === 'input') {
125
- return (
126
- <TextField
127
- variant="outlined"
128
- className="editable-field"
129
- value={value}
130
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleChange(e.target.value)}
131
- sx={mergeSx(inputFieldStyle, !errorMsg ? commonInputStyle : {})}
132
- error={Boolean(errorMsg)}
133
- helperText={errorMsg}
134
- disabled={disabled}
135
- slotProps={{
136
- input: {
137
- sx: { backgroundColor: 'transparent' },
138
- placeholder,
139
- },
140
- }}
141
- />
142
- );
143
- }
144
-
145
- const isTooLong = value.length > (maxLength || 300);
146
- return (
147
- <Box position="relative">
148
- <TextField
149
- variant="outlined"
150
- sx={mergeSx(inputFieldStyle, !errorMsg ? commonInputStyle : {})}
151
- value={value}
152
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleChange(e.target.value)}
153
- error={Boolean(errorMsg)}
154
- helperText={errorMsg}
155
- disabled={disabled}
156
- slotProps={{
157
- input: {
158
- multiline: true,
159
- minRows: rows,
160
- placeholder,
161
- },
162
- }}
163
- />
164
- {maxLength && maxLength > 0 ? (
165
- <Typography
166
- position="absolute"
167
- bottom={-22}
168
- right={2}
169
- variant="caption"
170
- fontSize="12px"
171
- component="span"
172
- color={isTooLong ? 'error' : 'text.secondary'}>
173
- {isTooLong ? `(${t('profile.maxInputLength')} ${maxLength}) ` : ''}
174
- {value.length} / {maxLength}
175
- </Typography>
176
- ) : null}
177
- </Box>
178
- );
179
- }, [value, handleChange, component, placeholder, rows, children]);
180
-
181
- if (!canEdit && editable) {
182
- return null;
183
- }
184
-
185
- if (!editable) {
186
- return value && !hidePreview ? (
187
- <Tooltip
188
- open={Boolean(mousePosition)}
189
- title={tooltip}
190
- placement="top"
191
- arrow
192
- slotProps={{
193
- popper: {
194
- // 使用虚拟锚点元素,基于鼠标位置
195
- anchorEl: mousePosition
196
- ? {
197
- getBoundingClientRect: () => ({
198
- top: mousePosition.mouseY,
199
- left: mousePosition.mouseX,
200
- right: mousePosition.mouseX,
201
- bottom: mousePosition.mouseY,
202
- width: 0,
203
- height: 0,
204
- x: mousePosition.mouseX,
205
- y: mousePosition.mouseY,
206
- toJSON: () => {},
207
- }),
208
- }
209
- : null,
210
- // 设置偏移,使tooltip显示在鼠标上方
211
- modifiers: [
212
- {
213
- name: 'offset',
214
- options: {
215
- offset: [0, 10],
216
- },
217
- },
218
- ],
219
- },
220
- }}>
221
- <Typography
222
- variant="subtitle1"
223
- component="div"
224
- gutterBottom
225
- sx={{
226
- width: '100%',
227
- mb: 0,
228
- lineHeight: 1.4,
229
- overflow: 'hidden',
230
- }}
231
- display="flex"
232
- alignItems="center"
233
- gap={1}>
234
- {icon
235
- ? React.cloneElement(icon as React.ReactElement<any>, {
236
- style: {
237
- filter: isDark ? 'brightness(0) saturate(100%) invert(1)' : 'none',
238
- },
239
- })
240
- : null}
241
- <Box display="flex" flexDirection="row" alignItems="center" width="90%">
242
- <Typography
243
- sx={{
244
- whiteSpace: 'pre-wrap',
245
- ...(inline ? { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } : {}),
246
- }}
247
- component="div"
248
- onMouseEnter={handleMouseEnter}
249
- onMouseLeave={handleMouseLeave}>
250
- {renderValue ? renderValue(value) : value}
251
- </Typography>
252
- {verified && (
253
- <VerifiedIcon color="success" style={{ fontSize: 16, width: 16, marginLeft: 4, flexShrink: 0 }} />
254
- )}
255
- </Box>
256
- </Typography>
257
- </Tooltip>
258
- ) : null;
259
- }
260
-
261
- return (
262
- <Box sx={{ width: '100%' }} style={style}>
263
- {label && (
264
- <Typography variant="subtitle1" gutterBottom sx={{ mb: 0.5, fontSize: '12px', color: 'text.primary' }}>
265
- {label}
266
- </Typography>
267
- )}
268
- {content}
269
- </Box>
270
- );
271
- }
272
-
273
- export default EditableField;
@@ -1,57 +0,0 @@
1
- /**
2
- * 用户中心 fallback 组件,用于没有权限访问时展示的页面
3
- */
4
-
5
- import React from 'react';
6
- import Empty from '@arcblock/ux/lib/Empty';
7
- import { translate } from '@arcblock/ux/lib/Locale/util';
8
- import { useMemoizedFn } from 'ahooks';
9
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
10
-
11
- import { translations } from '../libs/locales';
12
- import { UserCenterTab } from '../../@types';
13
- import { useUserFollowersContext } from '../../contexts/user-followers';
14
-
15
- function Fallback({
16
- currentActiveTab,
17
- isMyself,
18
- isSupportFollow = false,
19
- children,
20
- }: {
21
- currentActiveTab: UserCenterTab;
22
- isMyself: boolean;
23
- isSupportFollow?: boolean;
24
- children: React.ReactNode;
25
- }) {
26
- const { locale } = useLocaleContext();
27
- const t = useMemoizedFn((key, data = {}) => {
28
- return translate(translations, key, locale, 'en', data);
29
- });
30
- const { followed } = useUserFollowersContext();
31
-
32
- // 自己的页面或公开内容,直接显示
33
- if (isMyself || !currentActiveTab?.protected || currentActiveTab?.protected === 'all') {
34
- return children;
35
- }
36
-
37
- const { protected: protection } = currentActiveTab;
38
-
39
- // 如果还没有支持 follow 关系,但是已经设置了仅粉丝可见,则直接显示内容
40
- if (!isSupportFollow && protection === 'follower-only') {
41
- return children;
42
- }
43
- // 私密内容(仅自己可见)
44
- if (protection === true || protection === 'private') {
45
- return <Empty>{t('underProtected')}</Empty>;
46
- }
47
-
48
- // 仅粉丝可见内容
49
- if (protection === 'follower-only') {
50
- return followed ? children : <Empty>{t('followersOnly')}</Empty>;
51
- }
52
-
53
- // 未知的保护类型,默认不显示
54
- return <Empty>{t('underProtected')}</Empty>;
55
- }
56
-
57
- export default Fallback;
@@ -1,84 +0,0 @@
1
- import { Modal } from '@mui/material';
2
- import styled from '@emotion/styled';
3
- import NFTDisplay, { getNFTData } from '@arcblock/ux/lib/NFTDisplay';
4
-
5
- export interface NftInfo {
6
- address: string;
7
- data: Record<string, any>;
8
- display: Record<string, any>;
9
- issuer: string;
10
- }
11
-
12
- export default function NftPreview({
13
- visible,
14
- onClose,
15
- nft,
16
- }: {
17
- visible: boolean;
18
- onClose: () => void;
19
- nft: NftInfo | null;
20
- }) {
21
- if (!visible || !nft) {
22
- return null;
23
- }
24
-
25
- return (
26
- <NftPreviewRoot>
27
- {/* Preview Modal */}
28
- <Modal open={visible} onClose={onClose}>
29
- <ModalRoot onClick={onClose}>
30
- <NFTDisplay data={getNFTData(nft)} address={nft.address} inset />
31
- </ModalRoot>
32
- </Modal>
33
- </NftPreviewRoot>
34
- );
35
- }
36
-
37
- const NftPreviewRoot = styled.div`
38
- position: relative;
39
- width: 100%;
40
- height: 100%;
41
- cursor: pointer;
42
-
43
- &:hover {
44
- .mask {
45
- opacity: 1;
46
- }
47
- }
48
-
49
- .mask {
50
- position: absolute;
51
- top: 0;
52
- left: 0;
53
- display: flex;
54
- align-items: center;
55
- justify-content: center;
56
- width: 100%;
57
- height: 100%;
58
- background: rgba(0, 0, 0, 0.6);
59
- opacity: 0;
60
- transition: opacity 0.2s;
61
- }
62
- `;
63
-
64
- const ModalRoot = styled.div`
65
- display: flex;
66
- justify-content: center;
67
- align-items: center;
68
- height: 100vh;
69
- width: 100vw;
70
-
71
- img,
72
- object {
73
- max-width: 90vw;
74
- max-height: 75vh;
75
- }
76
-
77
- .nft-display--inset {
78
- > .MuiBox-root,
79
- .nft-display__loading {
80
- width: 75vmin;
81
- height: 75vmin;
82
- }
83
- }
84
- `;
@@ -1,279 +0,0 @@
1
- import { useState } from 'react';
2
- import { Box, Pagination, Skeleton, Typography, IconButton, Stack, alpha } from '@mui/material';
3
- import { useCreation, useMemoizedFn, useReactive, useRequest } from 'ahooks';
4
- import axios from 'axios';
5
- import { Icon } from '@iconify/react';
6
- import NFTDisplay, { getNFTData } from '@arcblock/ux/lib/NFTDisplay';
7
- import Empty from '@arcblock/ux/lib/Empty';
8
- import { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
9
- import { translate } from '@arcblock/ux/lib/Locale/util';
10
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
11
- import { joinURL } from 'ufo';
12
- import SocialShare from '@arcblock/ux/lib/SocialShare';
13
- import { User } from '../../@types';
14
- import { translations } from '../libs/locales';
15
- import NftPreview, { NftInfo } from './nft-preview';
16
-
17
- // 直接定义 SharedProps 类型
18
- interface SharedProps {
19
- title: string;
20
- url: string;
21
- }
22
-
23
- const maskStyle = (theme: any) => ({
24
- position: 'absolute',
25
- top: 0,
26
- left: 0,
27
- right: 0,
28
- bottom: 0,
29
- backgroundColor: 'rgba(0, 0, 0, 0.6)',
30
- opacity: 0,
31
- transition: 'opacity 0.3s ease-in-out',
32
- display: 'flex',
33
- alignItems: 'center',
34
- justifyContent: 'center',
35
- zIndex: 1,
36
- '& .mask-item': {
37
- backgroundColor: alpha(theme.palette.background.paper, 0.9),
38
- color: 'text.primary',
39
- '&:hover': {
40
- backgroundColor: alpha(theme.palette.background.paper, 1),
41
- },
42
- },
43
- });
44
-
45
- const CHAIN_EXPLORER_URL = 'https://main.abtnetwork.io/explorer';
46
-
47
- interface ResponseData {
48
- assets: NftInfo[];
49
- code: string;
50
- page: { cursor: string; next: boolean; total: number };
51
- }
52
-
53
- interface PaginationProps {
54
- page: number;
55
- size: number;
56
- }
57
-
58
- export default function Nft({ user }: { user: User }) {
59
- const { locale } = useLocaleContext();
60
- const t = useMemoizedFn((key, data = {}) => {
61
- return translate(translations, key, locale, 'en', data);
62
- });
63
-
64
- const [previewProps, setPreviewProps] = useState<{ visible: boolean; nft: NftInfo | null }>({
65
- visible: false,
66
- nft: null,
67
- });
68
-
69
- const [shareProps, setShareProps] = useState<{ anchorEl: HTMLElement | null; props: SharedProps | null }>({
70
- anchorEl: null,
71
- props: null,
72
- });
73
-
74
- const handleLinkClick = (nftAddress: string) => {
75
- const targetURL = joinURL(CHAIN_EXPLORER_URL, 'assets', nftAddress);
76
- window.open(targetURL, '_blank');
77
- };
78
-
79
- const handleShareClick = (element: HTMLElement, nft: NftInfo) => {
80
- let domain = '';
81
- if (typeof nft.data?.value === 'string') {
82
- domain = JSON.parse(nft.data?.value)?.domain;
83
- } else {
84
- domain = nft.data?.value?.domain;
85
- }
86
- setShareProps({
87
- anchorEl: element,
88
- props: {
89
- title: domain ? `Hey, I just won an NFT at the ${domain} event!` : 'Hey, I just won an NFT!',
90
- url: joinURL(CHAIN_EXPLORER_URL, 'assets', nft.address),
91
- },
92
- });
93
- };
94
-
95
- const handleViewClick = (nft: NftInfo) => {
96
- setPreviewProps({
97
- visible: true,
98
- nft,
99
- });
100
- };
101
-
102
- const paging = useReactive<PaginationProps>({
103
- page: 1,
104
- size: 20,
105
- });
106
- const userState = useRequest<ResponseData, [PaginationProps]>(
107
- async (pagination: PaginationProps = paging) => {
108
- const response = await axios.get(`${WELLKNOWN_SERVICE_PATH_PREFIX}/ocap/listAssets`, {
109
- params: {
110
- ownerAddress: user.did,
111
- ...pagination,
112
- },
113
- });
114
- return response.data;
115
- },
116
- {
117
- defaultParams: [paging],
118
- refreshDeps: [user.did, paging],
119
- }
120
- );
121
-
122
- const { loading, data } = userState;
123
-
124
- const dataPage = data?.page ?? { cursor: 0, next: false, total: 0 };
125
-
126
- const handlePageChange = (event: React.ChangeEvent<unknown>, value: number) => {
127
- paging.page = value;
128
- userState.run(paging);
129
- };
130
-
131
- const content = useCreation(() => {
132
- if (loading) {
133
- const skeletonItems = ['skeleton-1', 'skeleton-2', 'skeleton-3', 'skeleton-4', 'skeleton-5'].map((id) => (
134
- <Skeleton key={id} variant="rectangular" width="15%" height={166} sx={{ borderRadius: 1, flexShrink: 0 }} />
135
- ));
136
-
137
- return (
138
- <Box
139
- sx={{
140
- display: 'flex',
141
- flexDirection: 'column',
142
- gap: 2,
143
- }}>
144
- <Skeleton width="20%" />
145
- <Box
146
- sx={{
147
- display: 'flex',
148
- flexDirection: 'row',
149
- gap: 2,
150
- flexWrap: 'nowrap',
151
- }}>
152
- {skeletonItems}
153
- </Box>
154
- </Box>
155
- );
156
- }
157
- return (
158
- <>
159
- <Typography
160
- sx={{
161
- color: 'grey.A700',
162
- fontWeight: 600,
163
- mb: 2.5,
164
- }}>
165
- {t('common.nft')}
166
- </Typography>
167
-
168
- {data?.assets?.length === 0 && !loading && (
169
- <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', width: '100%', height: '100%' }}>
170
- <Empty>{t('common.noNFT')}</Empty>
171
- </Box>
172
- )}
173
- <Box
174
- className="nft-list-wrapper"
175
- sx={{
176
- display: 'grid',
177
- justifyItems: 'start',
178
- gridTemplateColumns: {
179
- xs: 'repeat(2, 1fr)',
180
- sm: 'repeat(3, 1fr)',
181
- md: 'repeat(3, 1fr)',
182
- lg: 'repeat(5, 1fr)',
183
- },
184
- gap: 2.5,
185
- }}>
186
- {data?.assets?.map((item) => (
187
- <Box
188
- key={item.address}
189
- sx={{
190
- flexShrink: 0,
191
- width: { xs: 120, sm: 120, md: 120, lg: 166 },
192
- height: { xs: 120, sm: 120, md: 120, lg: 166 },
193
- position: 'relative',
194
- borderRadius: 1,
195
- overflow: 'hidden',
196
- cursor: 'pointer',
197
- '&:hover .mask': {
198
- opacity: 1,
199
- },
200
- }}>
201
- <NFTDisplay
202
- data={getNFTData(item)}
203
- address={item.address}
204
- inset
205
- imageFilter={{
206
- imageFilter: 'resize',
207
- w: '500',
208
- f: 'webp',
209
- }}
210
- />
211
- <Box className="mask" sx={maskStyle}>
212
- <Stack direction="row" spacing={1}>
213
- <IconButton
214
- size="small"
215
- className="mask-item"
216
- onClick={(e) => {
217
- e.stopPropagation();
218
- handleLinkClick(item.address);
219
- }}>
220
- <Icon icon="tabler:link" fontSize={18} />
221
- </IconButton>
222
- <IconButton
223
- size="small"
224
- onClick={(e) => {
225
- e.stopPropagation();
226
- handleShareClick(e.currentTarget, item);
227
- }}
228
- className="mask-item">
229
- <Icon icon="tabler:share-2" fontSize={18} />
230
- </IconButton>
231
- <IconButton
232
- size="small"
233
- onClick={(e) => {
234
- e.stopPropagation();
235
- handleViewClick(item);
236
- }}
237
- className="mask-item">
238
- <Icon icon="tabler:eye" fontSize={18} />
239
- </IconButton>
240
- </Stack>
241
- </Box>
242
- </Box>
243
- ))}
244
- </Box>
245
- {dataPage.next || paging.page > 1 ? (
246
- <Pagination
247
- sx={{
248
- display: 'flex',
249
- justifyContent: 'center',
250
- mt: 2,
251
- }}
252
- page={paging.page}
253
- onChange={handlePageChange}
254
- count={Math.ceil(dataPage.total / paging.size)}
255
- size="small"
256
- />
257
- ) : null}
258
-
259
- <NftPreview
260
- visible={previewProps.visible && !!previewProps.nft}
261
- nft={previewProps.nft}
262
- onClose={() => {
263
- setPreviewProps({ visible: false, nft: null });
264
- }}
265
- />
266
-
267
- <SocialShare
268
- anchorEl={shareProps.anchorEl}
269
- onClose={() => {
270
- setShareProps({ anchorEl: null, props: null });
271
- }}
272
- sharedProps={shareProps.props || { title: '', url: '' }}
273
- />
274
- </>
275
- );
276
- }, [loading, dataPage, paging.page, paging.size, handlePageChange, shareProps, previewProps]);
277
-
278
- return <Box sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 1, p: 2, mb: 5 }}>{content}</Box>;
279
- }