@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,23 +0,0 @@
1
- import { Button } from '@mui/material';
2
- import { useMemoizedFn } from 'ahooks';
3
- import { translate } from '@arcblock/ux/lib/Locale/util';
4
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
5
-
6
- import { translations } from '../../../libs/locales';
7
- import { useUserFollowersContext } from '../../../../contexts/user-followers';
8
-
9
- function Follow() {
10
- const { locale } = useLocaleContext();
11
- const t = useMemoizedFn((key, data = {}) => {
12
- return translate(translations, key, locale, 'en', data);
13
- });
14
- const { followed, followUser, unfollowUser } = useUserFollowersContext();
15
-
16
- return (
17
- <Button variant="contained" onClick={() => (followed ? unfollowUser() : followUser())} fullWidth>
18
- {followed ? t('profile.unfollow') : t('profile.follow')}
19
- </Button>
20
- );
21
- }
22
-
23
- export default Follow;
@@ -1,17 +0,0 @@
1
- import { Box } from '@mui/material';
2
- import Chat from './chat';
3
- import Follow from './follow';
4
-
5
- import { User } from '../../../../@types';
6
-
7
- // 进入这里肯定是他人的个人中心
8
- function SocialActions({ user }: { user: User }) {
9
- return (
10
- <Box sx={{ display: 'flex', gap: 1 }}>
11
- <Chat user={user} />
12
- <Follow />
13
- </Box>
14
- );
15
- }
16
-
17
- export default SocialActions;
@@ -1,42 +0,0 @@
1
- import { memo } from 'react';
2
- import { Chip } from '@mui/material';
3
- import { Icon } from '@iconify/react';
4
- import SwapHorizRoundedIcon from '@iconify-icons/material-symbols/swap-horiz-rounded';
5
- import { useCreation } from 'ahooks';
6
- import type { User } from '../../../@types';
7
-
8
- function SwitchRole({ user, switchPassport }: { user: User; switchPassport: () => void }) {
9
- const currentRole = useCreation(
10
- // FIXME: @zhanghan 感觉应该把 name 的判断去掉?
11
- () => (user?.passports || [])?.find((item) => item.name === user.role || item.role === user.role),
12
- [user?.passports, user?.role]
13
- );
14
-
15
- return (
16
- <Chip
17
- label={currentRole?.title || user?.role || 'Guest'}
18
- size="small"
19
- variant="outlined"
20
- sx={{
21
- flexShrink: 0,
22
- fontWeight: 'bold',
23
- fontSize: '12px',
24
- color: 'text.primary',
25
- borderColor: 'grey.100',
26
- backgroundColor: 'transparent',
27
- textTransform: 'capitalize',
28
- pr: 1,
29
- pl: 0.5,
30
- '&:active': {
31
- boxShadow: 'none',
32
- },
33
- }}
34
- clickable
35
- deleteIcon={<Icon icon={SwapHorizRoundedIcon} color="inherit" />}
36
- onDelete={switchPassport}
37
- onClick={switchPassport}
38
- />
39
- );
40
- }
41
-
42
- export default memo(SwitchRole);
@@ -1,119 +0,0 @@
1
- import { useState, useEffect, useRef } from 'react';
2
- import { MenuItem, Select, SelectChangeEvent, ListSubheader, TextField } from '@mui/material';
3
- import { useDebounce, useMemoizedFn } from 'ahooks';
4
- import { KeyboardArrowDown as KeyboardArrowDownIcon } from '@mui/icons-material';
5
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
6
- import { translate } from '@arcblock/ux/lib/Locale/util';
7
- import Empty from '@arcblock/ux/lib/Empty';
8
- import { getTimezones } from './utils';
9
- import { translations } from '../../libs/locales';
10
-
11
- const timezones = getTimezones();
12
-
13
- interface TimezoneSelectProps {
14
- value: string;
15
- onChange: (value: string) => void;
16
- disabled?: boolean;
17
- mode?: 'drawer' | 'self';
18
- }
19
-
20
- export function TimezoneSelect({ value, onChange, disabled = false, mode = 'self' }: TimezoneSelectProps) {
21
- const { locale } = useLocaleContext();
22
- const t = useMemoizedFn((key, data = {}) => {
23
- return translate(translations, key, locale, 'en', data);
24
- });
25
- const [timezoneData, setTimezoneData] = useState(timezones);
26
- const [searchText, setSearchText] = useState('');
27
- const debouncedValue = useDebounce(searchText, { wait: 500 });
28
- const inputRef = useRef<HTMLInputElement>(null);
29
-
30
- const searchTimezones = useMemoizedFn((v: string) =>
31
- v ? timezones.filter((tz) => tz.value.toLowerCase().includes(v.toLowerCase())) : timezones
32
- );
33
-
34
- useEffect(() => {
35
- const data = searchTimezones(debouncedValue);
36
- setTimezoneData(data ?? timezones);
37
- // 数据更新后重新聚焦到输入框
38
- setTimeout(() => {
39
- inputRef.current?.focus();
40
- }, 0);
41
- }, [debouncedValue, searchTimezones]);
42
-
43
- return (
44
- <Select
45
- className={`timezone-select ${disabled ? 'disabled' : ''}`}
46
- value={value}
47
- onChange={(e: SelectChangeEvent) => onChange(e.target.value)}
48
- disabled={disabled}
49
- displayEmpty
50
- variant="outlined"
51
- // @ts-expect-error
52
- placeholder={t('profile.timezone')}
53
- // eslint-disable-next-line react/no-unstable-nested-components
54
- IconComponent={(props) => (
55
- <KeyboardArrowDownIcon
56
- {...props}
57
- sx={{ fontSize: 18, color: (theme) => `${theme.palette.text.secondary} !important` }}
58
- />
59
- )}
60
- MenuProps={{
61
- autoFocus: false,
62
- PaperProps: {
63
- style: {
64
- maxHeight: '400px',
65
- },
66
- },
67
- style: {
68
- zIndex: mode === 'drawer' ? 9999 : 1300,
69
- },
70
- }}
71
- sx={{
72
- width: '100%',
73
- '&:hover': {
74
- 'fieldset.MuiOutlinedInput-notchedOutline': {
75
- borderColor: 'divider',
76
- },
77
- },
78
- 'fieldset.MuiOutlinedInput-notchedOutline': {
79
- borderColor: 'divider',
80
- },
81
- }}>
82
- <ListSubheader>
83
- <TextField
84
- inputRef={inputRef}
85
- autoFocus
86
- value={searchText}
87
- placeholder={t('profile.timezone')}
88
- variant="outlined"
89
- size="small"
90
- fullWidth
91
- onChange={(event) => setSearchText(event.target.value)}
92
- onClick={(e) => e.stopPropagation()}
93
- onKeyDown={(e) => e.stopPropagation()}
94
- sx={{
95
- marginTop: '8px',
96
- '& .MuiOutlinedInput-root': {
97
- '& fieldset': {
98
- borderColor: 'divider',
99
- borderWidth: '1px',
100
- },
101
- '&:hover fieldset': {
102
- borderColor: 'divider',
103
- },
104
- '&.Mui-focused fieldset': {
105
- borderColor: 'divider',
106
- },
107
- },
108
- }}
109
- />
110
- </ListSubheader>
111
- {timezoneData.map((tz) => (
112
- <MenuItem key={tz.value} value={tz.value}>
113
- {tz.label}
114
- </MenuItem>
115
- ))}
116
- {timezoneData.length > 0 ? null : <Empty>{t('emptyContent')}</Empty>}
117
- </Select>
118
- );
119
- }
@@ -1,292 +0,0 @@
1
- import { Box, Divider, Typography, IconButton, Collapse } from '@mui/material';
2
- import type { BoxProps } from '@mui/material';
3
- import Avatar from '@arcblock/ux/lib/Avatar';
4
- import DID from '@arcblock/ux/lib/DID';
5
- import { useMemoizedFn } from 'ahooks';
6
- import { translate } from '@arcblock/ux/lib/Locale/util';
7
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
8
- import noop from 'lodash/noop';
9
- import { lazy, useEffect, useState } from 'react';
10
- import Toast from '@arcblock/ux/lib/Toast';
11
- import type { AxiosError } from 'axios';
12
- import { parseURL, joinURL } from 'ufo';
13
- import {
14
- KeyboardArrowDown as KeyboardArrowDownIcon,
15
- KeyboardArrowUp as KeyboardArrowUpIcon,
16
- } from '@mui/icons-material';
17
- import { getBlockletSDK } from '@blocklet/js-sdk';
18
-
19
- import { translations } from '../../libs/locales';
20
- import type { User, UserAddress, UserMetadata } from '../../../@types';
21
- import { formatAxiosError } from '../../libs/utils';
22
- import { currentTimezone, getStatusDuration, isValidUrl, isDuplicateUrl } from './utils';
23
- import SwitchRole from './switch-role';
24
-
25
- import UserStatus from './user-status';
26
- import UserInfo from './user-info';
27
- import SocialActions from './social-actions';
28
-
29
- const UserMetadataComponent = lazy(() => import('./metadata'));
30
-
31
- export default function UserBasicInfo({
32
- user,
33
- isMyself = true,
34
- showFullDid = true,
35
- switchPassport,
36
- switchProfile,
37
- isMobile = false,
38
- onlyProfile = false,
39
- refreshProfile,
40
- isShowSocialActions = false,
41
- ...rest
42
- }: {
43
- user: User;
44
- isMyself?: boolean;
45
- showFullDid?: boolean;
46
- switchPassport: () => void;
47
- switchProfile: () => void;
48
- size?: number;
49
- isMobile?: boolean;
50
- onlyProfile?: boolean;
51
- refreshProfile: () => void;
52
- isShowSocialActions?: boolean;
53
- } & BoxProps) {
54
- const client = getBlockletSDK();
55
- const { locale } = useLocaleContext();
56
- const [userStatus, setUserStatus] = useState<UserMetadata['status']>(undefined);
57
- const t = useMemoizedFn((key, data = {}) => {
58
- return translate(translations, key, locale, 'en', data);
59
- });
60
-
61
- const [expanded, setExpanded] = useState(!isMobile || onlyProfile);
62
-
63
- useEffect(() => {
64
- setUserStatus(user?.metadata?.status);
65
- }, [user]);
66
-
67
- // Add effect to handle mobile state changes
68
- useEffect(() => {
69
- setExpanded(!isMobile || onlyProfile);
70
- }, [isMobile, onlyProfile]);
71
-
72
- const onUpdateUserStatus = async (v: UserMetadata['status']) => {
73
- if (!isMyself) {
74
- return;
75
- }
76
- try {
77
- if (v) {
78
- const dateRange = getStatusDuration(v);
79
- v.dateRange = dateRange.length > 0 ? dateRange : (userStatus?.dateRange ?? []);
80
- }
81
- setUserStatus(v);
82
- await client.user.saveProfile({
83
- // @ts-ignore
84
- metadata: {
85
- ...(user?.metadata ?? { joinedAt: user?.createdAt, email: user?.email, phone: user?.phone }),
86
- status: v || {},
87
- },
88
- });
89
- refreshProfile();
90
- } catch (err) {
91
- console.error(err);
92
- Toast.error(formatAxiosError(err as AxiosError));
93
- }
94
- };
95
-
96
- const toggleExpand = () => {
97
- setExpanded(!expanded);
98
- };
99
-
100
- const onSave = async (v: { metadata: UserMetadata; address: UserAddress }) => {
101
- if (!isMyself) {
102
- return;
103
- }
104
- const { metadata, address } = v;
105
- try {
106
- const newLinks =
107
- metadata?.links
108
- ?.map((link, index) => {
109
- if (!link.url || !isValidUrl(link.url)) return null;
110
-
111
- // 去重:如果 URL 相同则跳过(忽略协议和大 小写)
112
- if (index > 0) {
113
- const prevLinks = metadata.links?.slice(0, index);
114
- if (prevLinks?.some((l) => isDuplicateUrl(l.url, link.url))) {
115
- return null;
116
- }
117
- }
118
-
119
- try {
120
- const parsedUrl = parseURL(link.url);
121
- // 如果没有协议,添加 https
122
- if (!parsedUrl.protocol) {
123
- link.url = joinURL('https://', link.url);
124
- }
125
- return link;
126
- } catch (e) {
127
- console.error('Invalid URL:', link.url);
128
- return null;
129
- }
130
- })
131
- .filter((l) => !!l) || [];
132
- metadata.links = newLinks;
133
- // @ts-ignore
134
- await client.user.saveProfile({ metadata, address });
135
- refreshProfile();
136
- } catch (err) {
137
- console.error(err);
138
- Toast.error(formatAxiosError(err as AxiosError));
139
- }
140
- };
141
-
142
- return (
143
- <Box
144
- {...rest}
145
- sx={{
146
- position: 'relative',
147
- ...(rest.sx ?? {}),
148
- }}>
149
- <Box
150
- className="user-info"
151
- sx={{
152
- display: 'flex',
153
- flexDirection: isMobile ? 'row' : 'column',
154
- gap: 2,
155
- }}>
156
- <Box
157
- className="user-avatar"
158
- sx={{
159
- position: 'relative',
160
- display: 'flex',
161
- alignItems: 'center',
162
- justifyContent: 'space-between',
163
- }}>
164
- <Avatar
165
- // @ts-ignore
166
- src={user?.avatar}
167
- did={user?.did}
168
- size={rest.size || (isMobile ? 64 : 100)}
169
- variant="circle"
170
- shape="circle"
171
- sx={{
172
- borderRadius: '100%',
173
- backgroundColor: '#fff',
174
- position: 'relative',
175
- overflow: 'hidden',
176
- flexShrink: 0,
177
- ...(isMyself
178
- ? {
179
- cursor: 'pointer',
180
- '&::after': {
181
- content: `"${t('switchProfile')}"`,
182
- color: 'white',
183
- position: 'absolute',
184
- fontSize: '12px',
185
- bottom: 0,
186
- left: 0,
187
- right: 0,
188
- height: '25%',
189
- backgroundColor: 'rgba(0, 0, 0, 0.3)',
190
- display: 'flex',
191
- justifyContent: 'center',
192
- alignItems: 'center',
193
- },
194
- }
195
- : {}),
196
- }}
197
- onClick={isMyself ? switchProfile : noop}
198
- />
199
- <UserStatus
200
- isMobile={isMobile}
201
- size={rest.size || (isMobile ? 64 : 100)}
202
- isMyself={isMyself}
203
- timezone={user?.metadata?.timezone || currentTimezone}
204
- status={userStatus}
205
- onChange={onUpdateUserStatus}
206
- />
207
- </Box>
208
- <Box
209
- sx={{
210
- flex: 1,
211
- overflow: 'hidden',
212
- }}>
213
- <Typography
214
- variant="h6"
215
- component="div"
216
- sx={{
217
- flex: 1,
218
- fontWeight: 600,
219
- display: 'flex',
220
- alignItems: 'center',
221
- gap: 1,
222
- fontSize: '24px !important',
223
- flexWrap: 'wrap',
224
- }}>
225
- <span
226
- style={{
227
- overflow: 'hidden',
228
- textOverflow: 'ellipsis',
229
- whiteSpace: 'nowrap',
230
- }}>
231
- {user?.fullName}
232
- </span>
233
- {isMyself ? <SwitchRole user={user} switchPassport={switchPassport} /> : null}
234
- </Typography>
235
- <DID
236
- did={user.did}
237
- size={16}
238
- showQrcode
239
- copyable
240
- compact={!showFullDid}
241
- responsive={!showFullDid}
242
- locale={locale}
243
- />
244
- </Box>
245
- </Box>
246
- {!isMyself && isShowSocialActions ? (
247
- <Box sx={{ mt: 2 }}>
248
- <SocialActions user={user} />
249
- </Box>
250
- ) : null}
251
- <UserMetadataComponent isMobile={isMobile} isMyself={isMyself} user={user} onSave={onSave} />
252
- {isMyself ? (
253
- <>
254
- <Divider sx={{ my: isMobile ? 1 : 3 }} />
255
- {isMobile && !onlyProfile ? (
256
- <Box
257
- sx={{
258
- display: 'flex',
259
- justifyContent: 'center',
260
- mb: 0,
261
- }}>
262
- <IconButton
263
- size="small"
264
- onClick={toggleExpand}
265
- sx={{
266
- backgroundColor: 'grey.50',
267
- '&:hover': {
268
- backgroundColor: 'grey.50',
269
- opacity: 0.8,
270
- },
271
- }}>
272
- {expanded ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
273
- </IconButton>
274
- </Box>
275
- ) : null}
276
- <Collapse in={expanded} timeout="auto">
277
- <Typography
278
- component="p"
279
- sx={{
280
- color: 'text.secondary',
281
- fontSize: '14px',
282
- mb: 2,
283
- }}>
284
- {t('profile.justForYou')}
285
- </Typography>
286
- <UserInfo user={user} isMySelf={isMyself} />
287
- </Collapse>
288
- </>
289
- ) : null}
290
- </Box>
291
- );
292
- }
@@ -1,54 +0,0 @@
1
- import { Box, BoxProps, Typography } from '@mui/material';
2
- import { Verified as VerifiedIcon } from '@mui/icons-material';
3
-
4
- type TUserInfoItemProps = {
5
- data: {
6
- icon: any;
7
- title: string;
8
- content: any;
9
- };
10
- verified?: boolean;
11
- };
12
-
13
- export default function UserInfoItem({ data, verified = false, ...rest }: TUserInfoItemProps & BoxProps) {
14
- return (
15
- <Box
16
- {...rest}
17
- sx={{
18
- display: 'flex',
19
- alignItems: 'center',
20
- justifyContent: 'space-between',
21
- ...rest.sx,
22
- }}>
23
- <Typography
24
- sx={{
25
- display: 'flex',
26
- alignItems: 'center',
27
- color: 'text.primary',
28
- fontSize: '14px',
29
- gap: 1,
30
- fontWeight: 500,
31
- }}>
32
- {data.icon}
33
- {data.title}
34
- </Typography>
35
- <Box
36
- sx={{
37
- display: 'flex',
38
- flexDirection: 'row',
39
- alignItems: 'center',
40
- }}>
41
- <Typography
42
- component="div"
43
- sx={{
44
- color: 'text.secondary',
45
- whiteSpace: 'pre-wrap',
46
- fontSize: '14px',
47
- }}>
48
- {data.content}
49
- </Typography>
50
- {verified && <VerifiedIcon color="success" style={{ fontSize: 16, marginLeft: 4 }} />}
51
- </Box>
52
- </Box>
53
- );
54
- }
@@ -1,91 +0,0 @@
1
- import { Box } from '@mui/material';
2
- import type { BoxProps } from '@mui/material';
3
- import { Icon } from '@iconify/react';
4
- import { useMemoizedFn, useCreation } from 'ahooks';
5
- import DID from '@arcblock/ux/lib/DID';
6
- import ScheduleOutlineRoundedIcon from '@iconify-icons/material-symbols/schedule-outline-rounded';
7
- import MoreTimeRoundedIcon from '@iconify-icons/material-symbols/more-time-rounded';
8
- import CaptivePortalRoundedIcon from '@iconify-icons/material-symbols/captive-portal-rounded';
9
- import SettingsInputAntennaRoundedIcon from '@iconify-icons/material-symbols/settings-input-antenna-rounded';
10
- import RelativeTime from '@arcblock/ux/lib/RelativeTime';
11
- import { translate } from '@arcblock/ux/lib/Locale/util';
12
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
13
- import { LOGIN_PROVIDER_NAME } from '@arcblock/ux/lib/Util/constant';
14
- import ShortenLabel from '@arcblock/ux/lib/UserCard/Content/shorten-label';
15
- import { translations } from '../../libs/locales';
16
- import UserInfoItem from './user-info-item';
17
- import type { User } from '../../../@types';
18
-
19
- export default function UserInfo({
20
- user,
21
- isMySelf = false,
22
- ...rest
23
- }: {
24
- user: User;
25
- isMySelf?: boolean;
26
- } & BoxProps) {
27
- const { locale } = useLocaleContext();
28
- const t = useMemoizedFn((key, data = {}) => {
29
- return translate(translations, key, locale, 'en', data);
30
- });
31
-
32
- const readableProvider = useCreation(() => {
33
- return (user?.sourceProvider && LOGIN_PROVIDER_NAME[user.sourceProvider]) || t('unknown');
34
- }, [user?.sourceProvider]);
35
-
36
- const userInfoListData = [];
37
- if (isMySelf) {
38
- userInfoListData.push({
39
- icon: <Icon fontSize={16} icon={ScheduleOutlineRoundedIcon} />,
40
- title: t('lastLoginAt'),
41
- content: user?.lastLoginAt ? (
42
- // @ts-ignore
43
- <RelativeTime locale={locale} value={user?.lastLoginAt} relativeRange={3 * 86400 * 1000} />
44
- ) : (
45
- t('unknown')
46
- ),
47
- });
48
- userInfoListData.push({
49
- icon: <Icon fontSize={16} icon={SettingsInputAntennaRoundedIcon} />,
50
- title: t('lastLoginIp'),
51
- content: user?.lastLoginIp ? <ShortenLabel maxLength={20}>{user?.lastLoginIp}</ShortenLabel> : t('unknown'),
52
- });
53
- }
54
- userInfoListData.push({
55
- icon: <Icon fontSize={16} icon={MoreTimeRoundedIcon} />,
56
- title: t('createdAt'),
57
- // @ts-ignore
58
- content: user?.createdAt ? <RelativeTime locale={locale} value={user?.createdAt} /> : t('unknown'),
59
- });
60
- if (isMySelf) {
61
- userInfoListData.push({
62
- icon: <Icon fontSize={16} icon={CaptivePortalRoundedIcon} />,
63
- title: t('registerFrom'),
64
- content: readableProvider,
65
- });
66
- if (user?.inviter) {
67
- userInfoListData.push({
68
- icon: <Icon fontSize={16} icon={CaptivePortalRoundedIcon} />,
69
- title: t('invitedBy'),
70
- content: (
71
- <DID style={{ maxWidth: 260 }} did={user.inviter} showQrcode copyable compact responsive locale={locale} />
72
- ),
73
- });
74
- }
75
- }
76
-
77
- return (
78
- <Box
79
- {...rest}
80
- sx={{
81
- display: 'flex',
82
- flexDirection: 'column',
83
- gap: 1.5,
84
- ...rest?.sx,
85
- }}>
86
- {userInfoListData.map((item) => (
87
- <UserInfoItem key={item.title} data={item} sx={{ flex: 1 }} />
88
- ))}
89
- </Box>
90
- );
91
- }