@arcblock/ux 2.11.25 → 2.11.27

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.
@@ -1,28 +1,26 @@
1
- import React from 'react';
1
+ import { ModalProps } from '@mui/material';
2
2
  import { IDidAddressWrapper } from '../Address';
3
3
  import { HTMLDidAddressElement } from '../Address/did-address';
4
- import type { Locale } from '../type';
5
- interface IDIDPropTypes extends IDidAddressWrapper {
4
+ interface DIDOwnProps {
6
5
  did: string;
7
- size?: number;
8
- component?: React.ElementType;
9
- copyable?: true | false;
10
- responsive?: true | false;
11
- showCopyButtonInTooltip?: false | true;
12
- showAvatar?: true | false;
13
- showQrcode?: false | true;
14
- inline?: false | true;
15
- append?: any;
16
- compact?: false | true;
17
- startChars?: number;
18
- endChars?: number;
19
- locale?: Locale;
20
6
  chainId?: string;
21
7
  roleType?: number;
8
+ showAvatar?: true | false;
9
+ showQrcode?: false | true;
10
+ }
11
+ export interface DIDProps extends DIDOwnProps, Omit<IDidAddressWrapper, 'ref'> {
22
12
  }
23
13
  export interface HTMLDIDElement extends HTMLDidAddressElement {
24
14
  openQRCode: () => void;
25
15
  closeQRCode: () => void;
26
16
  }
27
- declare const DID: React.ForwardRefExoticComponent<Omit<IDIDPropTypes, "ref"> & React.RefAttributes<HTMLDIDElement>>;
17
+ export declare const DID: import("react").ForwardRefExoticComponent<DIDProps & import("react").RefAttributes<HTMLDIDElement>>;
18
+ export interface DIDDialogProps extends DIDProps {
19
+ open: boolean;
20
+ fullScreen?: false | true;
21
+ fullWidth?: false | true;
22
+ scroll?: 'body' | 'paper';
23
+ onClose?: ModalProps['onClose'];
24
+ }
25
+ export declare function DIDDialog({ did, chainId, roleType, showAvatar, open, fullScreen, fullWidth, scroll, onClose, locale, ...rest }: DIDDialogProps): import("react/jsx-runtime").JSX.Element;
28
26
  export default DID;
package/lib/DID/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { getDIDMotifInfo } from '@arcblock/did-motif';
3
3
  import { types } from '@ocap/mcrypto';
4
4
  import QRCode from 'qrcode.react';
@@ -6,7 +6,7 @@ import { Icon } from '@iconify/react';
6
6
  import IconQrCode from '@iconify-icons/material-symbols/qr-code-rounded';
7
7
  import { Box, Dialog, DialogContent, Typography } from '@mui/material';
8
8
  import { useCreation, useMemoizedFn } from 'ahooks';
9
- import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react';
9
+ import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
10
10
  import Address from '../Address';
11
11
  import Avatar from '../Avatar';
12
12
  import { temp as colors } from '../Colors';
@@ -27,6 +27,7 @@ const translations = {
27
27
  };
28
28
  const DEFAULT_CHAIN_ID = 'xenon-2020-01-15';
29
29
  const CHAIN_ID_MAP = {
30
+ main: DEFAULT_CHAIN_ID,
30
31
  'main.abtnetwork.io': DEFAULT_CHAIN_ID,
31
32
  'beta.abtnetwork.io': 'beta'
32
33
  };
@@ -68,9 +69,52 @@ const getAvatarSize = (didMotifInfo, isEthDid, size) => {
68
69
  }
69
70
  return size;
70
71
  };
71
- const DID = /*#__PURE__*/forwardRef((props, ref) => {
72
+ function useDIDInfo({
73
+ did,
74
+ showAvatar
75
+ }) {
76
+ const isEthDid = isEthereumDid(did);
77
+ const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(did);
78
+ const content = useCreation(() => {
79
+ if (isEthDid) {
80
+ return did;
81
+ }
82
+ return `${DID_PREFIX}${did}`;
83
+ }, [did, isEthDid]);
84
+ const getPrepend = useMemoizedFn((avatarSize, keyPrefix) => [/*#__PURE__*/_jsx("span", {
85
+ style: {
86
+ flex: '0 0 auto',
87
+ color: getFontColor(did, didMotifInfo, isEthDid)
88
+ },
89
+ children: "DID:"
90
+ }, `${keyPrefix}-prefix-did-${avatarSize}`), /*#__PURE__*/_jsxs("span", {
91
+ className: "did-address-text",
92
+ children: [isEthDid ? 'ETH' : 'ABT', ":"]
93
+ }, `${keyPrefix}-prefix-abt-${avatarSize}`), showAvatar && /*#__PURE__*/_jsx(Avatar, {
94
+ src: "",
95
+ did: did,
96
+ size: getAvatarSize(didMotifInfo, isEthDid, avatarSize || 18),
97
+ style: {
98
+ display: 'inline-flex',
99
+ alignItems: 'center',
100
+ marginLeft: 2,
101
+ marginRight: 4
102
+ },
103
+ blockiesPadding: false,
104
+ className: "did-address-avatar"
105
+ }, `${keyPrefix}-avatar-${avatarSize}`)]);
106
+ return {
107
+ isEthDid,
108
+ didMotifInfo,
109
+ content,
110
+ getPrepend
111
+ };
112
+ }
113
+ export const DID = /*#__PURE__*/forwardRef((props, ref) => {
72
114
  const {
73
115
  did,
116
+ chainId,
117
+ roleType,
74
118
  showAvatar = true,
75
119
  showQrcode = false,
76
120
  locale = 'en',
@@ -104,48 +148,14 @@ const DID = /*#__PURE__*/forwardRef((props, ref) => {
104
148
  sx
105
149
  };
106
150
  const addressRef = useRef(null);
107
- const t = useMemoizedFn((key, data = {}) => {
108
- return translate(translations, key, locale, 'en', data);
151
+ const {
152
+ content,
153
+ getPrepend
154
+ } = useDIDInfo({
155
+ did,
156
+ showAvatar
109
157
  });
110
- let chainId = props.chainId || '';
111
- try {
112
- if (!chainId) {
113
- const chainHostUrl = window.blocklet?.CHAIN_HOST;
114
- if (chainHostUrl) {
115
- const chainHost = new URL(chainHostUrl).hostname;
116
- if (chainHost) {
117
- chainId = CHAIN_ID_MAP[chainHost];
118
- }
119
- }
120
- }
121
- } catch {
122
- console.warn('Failed to parse chainHost');
123
- }
124
158
  const [open, setOpen] = useState(false);
125
- const isEthDid = isEthereumDid(did);
126
- const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(did);
127
- const getPrepend = (avatarSize, keyPrefix) => [/*#__PURE__*/_jsx("span", {
128
- style: {
129
- flex: '0 0 auto',
130
- color: getFontColor(did, didMotifInfo, isEthDid)
131
- },
132
- children: "DID:"
133
- }, `${keyPrefix}-prefix-did-${avatarSize}`), /*#__PURE__*/_jsx("span", {
134
- className: "did-address-text",
135
- children: "ABT:"
136
- }, `${keyPrefix}-prefix-abt-${avatarSize}`), showAvatar && /*#__PURE__*/_jsx(Avatar, {
137
- src: "",
138
- did: did,
139
- size: getAvatarSize(didMotifInfo, isEthDid, avatarSize || 18),
140
- style: {
141
- display: 'inline-flex',
142
- alignItems: 'center',
143
- marginLeft: 2,
144
- marginRight: 4
145
- },
146
- blockiesPadding: false,
147
- className: "did-address-avatar"
148
- }, `${keyPrefix}-avatar-${avatarSize}`)];
149
159
  const closeQrCode = useMemoizedFn(() => {
150
160
  setOpen(false);
151
161
  });
@@ -164,34 +174,10 @@ const DID = /*#__PURE__*/forwardRef((props, ref) => {
164
174
  }
165
175
  });
166
176
  });
167
- const downloadUrl = useCreation(() => {
168
- if (['zh', 'en'].includes(locale)) {
169
- return `https://www.didwallet.io/${locale}`;
170
- }
171
- return 'https://www.didwallet.io/en';
172
- }, [locale]);
173
- const downloadTips = useCreation(() => {
174
- return /*#__PURE__*/_jsxs(_Fragment, {
175
- children: [t('downloadTips'), ' ', /*#__PURE__*/_jsx(Box, {
176
- component: "a",
177
- href: downloadUrl,
178
- target: "_blank",
179
- rel: "noreferrer",
180
- sx: {
181
- color: colors.foregroundsFgInteractive,
182
- textDecoration: 'none',
183
- '&:hover': {
184
- textDecoration: 'underline'
185
- }
186
- },
187
- children: t('download')
188
- })]
189
- });
190
- }, [downloadUrl]);
191
177
  return /*#__PURE__*/_jsxs(_Fragment, {
192
178
  children: [/*#__PURE__*/_jsx(Address, {
193
179
  locale: locale,
194
- content: `${DID_PREFIX}${did}`,
180
+ content: content,
195
181
  ...rest,
196
182
  ref: addressRef,
197
183
  prepend: getPrepend(rest.size, 'address'),
@@ -210,62 +196,152 @@ const DID = /*#__PURE__*/forwardRef((props, ref) => {
210
196
  }) : null, rest.append]
211
197
  }),
212
198
  children: did
213
- }, "address"), /*#__PURE__*/_jsx(Dialog, {
199
+ }, "address"), /*#__PURE__*/_jsx(DIDDialog, {
200
+ did: did,
201
+ chainId: chainId,
202
+ roleType: roleType,
203
+ showAvatar: showAvatar,
214
204
  open: open,
215
205
  onClose: closeQrCode,
216
- maxWidth: "sm",
217
- PaperProps: {
206
+ ...rest
207
+ })]
208
+ });
209
+ });
210
+ export function DIDDialog({
211
+ did,
212
+ chainId,
213
+ roleType,
214
+ showAvatar = true,
215
+ // DialogProps
216
+ open,
217
+ fullScreen = false,
218
+ fullWidth = false,
219
+ scroll = 'paper',
220
+ onClose,
221
+ // AddressProps
222
+ locale = 'en',
223
+ ...rest
224
+ }) {
225
+ const t = useMemoizedFn((key, data = {}) => {
226
+ return translate(translations, key, locale, 'en', data);
227
+ });
228
+ const {
229
+ isEthDid,
230
+ content,
231
+ didMotifInfo,
232
+ getPrepend
233
+ } = useDIDInfo({
234
+ did,
235
+ showAvatar
236
+ });
237
+ const downloadUrl = useCreation(() => {
238
+ if (['zh', 'en'].includes(locale)) {
239
+ return `https://www.didwallet.io/${locale}`;
240
+ }
241
+ return 'https://www.didwallet.io/en';
242
+ }, [locale]);
243
+ const downloadTips = useCreation(() => {
244
+ return /*#__PURE__*/_jsxs(_Fragment, {
245
+ children: [t('downloadTips'), ' ', /*#__PURE__*/_jsx(Box, {
246
+ component: "a",
247
+ href: downloadUrl,
248
+ target: "_blank",
249
+ rel: "noreferrer",
218
250
  sx: {
219
- boxShadow: 'none',
220
- borderRadius: '12px'
221
- }
251
+ color: colors.foregroundsFgInteractive,
252
+ textDecoration: 'none',
253
+ '&:hover': {
254
+ textDecoration: 'underline'
255
+ }
256
+ },
257
+ children: t('download')
258
+ })]
259
+ });
260
+ }, [downloadUrl]);
261
+ const _chainId = useCreation(() => {
262
+ if (chainId) {
263
+ return CHAIN_ID_MAP[chainId] || chainId;
264
+ }
265
+
266
+ // 以太坊 DID 使用默认chainId '1'
267
+ if (isEthDid) return '1';
268
+
269
+ // 解析 chainHost 并获取对应的chainId
270
+ try {
271
+ const chainHostUrl = window.blocklet?.CHAIN_HOST;
272
+ const chainHost = new URL(chainHostUrl).hostname;
273
+ if (chainHost) {
274
+ return CHAIN_ID_MAP[chainHost] || DEFAULT_CHAIN_ID;
275
+ }
276
+ } catch (error) {
277
+ console.warn('Failed to parse chainHost:', error);
278
+ }
279
+ return DEFAULT_CHAIN_ID;
280
+ }, [isEthDid, chainId]);
281
+ const qrCodeLink = useCreation(() => {
282
+ if (isEthDid) {
283
+ return `ethereum:abtwallet.io/i?address=${content}&action=didRecognize&chainID=${_chainId}`;
284
+ }
285
+ return `abt://abtwallet.io/i?did=${content}&action=didRecognize&chainID=${_chainId}`;
286
+ }, [content, isEthDid, _chainId]);
287
+ return /*#__PURE__*/_jsx(Dialog, {
288
+ open: open,
289
+ onClose: onClose,
290
+ fullScreen: fullScreen,
291
+ fullWidth: fullWidth,
292
+ scroll: scroll,
293
+ maxWidth: "sm",
294
+ PaperProps: {
295
+ sx: {
296
+ boxShadow: 'none',
297
+ borderRadius: '12px'
298
+ }
299
+ },
300
+ children: /*#__PURE__*/_jsxs(DialogContent, {
301
+ align: "center",
302
+ sx: {
303
+ p: 3
222
304
  },
223
- children: /*#__PURE__*/_jsxs(DialogContent, {
224
- align: "center",
305
+ children: [/*#__PURE__*/_jsx(Typography, {
225
306
  sx: {
226
- p: 3
307
+ mb: 2,
308
+ fontWeight: 500,
309
+ fontSize: 18
227
310
  },
228
- children: [/*#__PURE__*/_jsx(Typography, {
229
- sx: {
230
- mb: 2,
231
- fontWeight: 500,
232
- fontSize: 18
233
- },
234
- children: t('scanQrcode', {
235
- role: getRoleName(props.roleType || didMotifInfo?.roleType)
236
- })
237
- }), /*#__PURE__*/_jsx(QRCode
238
- // eslint-disable-next-line max-len
239
- , {
240
- value: `abt://abtwallet.io/i?did=${DID_PREFIX}${did}&action=didRecognize&chainID=${chainId || DEFAULT_CHAIN_ID}`,
241
- size: 256,
242
- renderAs: "svg",
243
- level: "M"
244
- }), /*#__PURE__*/_jsx(Box, {
245
- sx: {
246
- mt: 1.5,
247
- textAlign: 'center'
248
- },
249
- children: /*#__PURE__*/_jsx(Address, {
250
- locale: locale,
251
- content: `${DID_PREFIX}${did}`,
252
- prepend: getPrepend(16, 'dialog'),
253
- ...rest,
254
- size: 16,
255
- copyable: true,
256
- children: did
257
- }, "dialog-address")
258
- }), /*#__PURE__*/_jsx(Typography, {
259
- variant: "body2",
260
- sx: {
261
- color: colors.textSubtitle,
262
- fontSize: '12px',
263
- mt: 1
264
- },
265
- children: downloadTips
266
- })]
267
- })
268
- })]
311
+ children: t('scanQrcode', {
312
+ role: getRoleName(roleType || didMotifInfo?.roleType)
313
+ })
314
+ }), /*#__PURE__*/_jsx(QRCode
315
+ // eslint-disable-next-line max-len
316
+ , {
317
+ value: qrCodeLink,
318
+ size: 256,
319
+ renderAs: "svg",
320
+ level: "M"
321
+ }), /*#__PURE__*/_jsx(Box, {
322
+ sx: {
323
+ mt: 1.5,
324
+ textAlign: 'center'
325
+ },
326
+ children: /*#__PURE__*/_jsx(Address, {
327
+ locale: locale,
328
+ content: content,
329
+ prepend: getPrepend(16, 'dialog'),
330
+ ...rest,
331
+ size: 16,
332
+ copyable: true,
333
+ children: did
334
+ }, "dialog-address")
335
+ }), /*#__PURE__*/_jsx(Typography, {
336
+ variant: "body2",
337
+ sx: {
338
+ color: colors.textSubtitle,
339
+ fontSize: '12px',
340
+ mt: 1
341
+ },
342
+ children: downloadTips
343
+ })]
344
+ })
269
345
  });
270
- });
346
+ }
271
347
  export default DID;
@@ -40,3 +40,6 @@ export type DataTableProps = {
40
40
  durable?: string;
41
41
  durableKeys?: "page" | "rowsPerPage" | "searchText" | "sortOrder";
42
42
  } & ModifiedMUIDataTableProps;
43
+ import { TableFilterList } from 'mui-datatables';
44
+ import { TableFooter } from 'mui-datatables';
45
+ export { TableFilterList, TableFooter };
@@ -627,4 +627,5 @@ const FooterContainer = styled('div')`
627
627
  margin-left: 10px;
628
628
  }
629
629
  }
630
- `;
630
+ `;
631
+ export { TableFilterList, TableFooter };
@@ -14,7 +14,7 @@ export interface HeaderProps extends Omit<BoxProps, 'maxWidth'> {
14
14
  prepend?: React.ReactNode;
15
15
  align?: 'left' | 'right';
16
16
  maxWidth?: Breakpoint | false;
17
- homeLink?: string | ((brandContent: React.ReactNode) => React.ReactNode);
17
+ homeLink?: string | ((brandContent: React.ReactNode) => JSX.Element | null);
18
18
  }
19
19
  /**
20
20
  * Header 组件
@@ -7,7 +7,7 @@ export declare const RELAY_SOCKET_PREFIX = "/.well-known/service";
7
7
  export declare const API_DID_PREFIX = "/api/did";
8
8
  export declare const DASHBOARD_URL = "/.well-known/service/admin";
9
9
  export declare const PROFILE_URL = "/.well-known/service/user";
10
- export declare const DID_SPACE_URL = "/.well-known/service/user/settings#storage";
10
+ export declare const DID_SPACE_URL = "/.well-known/service/user/did-spaces";
11
11
  export declare const NAVIGATION_URL = "/.well-known/service/admin/navigation";
12
12
  export declare const DID_PREFIX = "did:abt:";
13
13
  export declare const PASSPORT_STATUS: {
@@ -7,7 +7,7 @@ export const RELAY_SOCKET_PREFIX = '/.well-known/service';
7
7
  export const API_DID_PREFIX = '/api/did';
8
8
  export const DASHBOARD_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/admin`;
9
9
  export const PROFILE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user`;
10
- export const DID_SPACE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user/settings#storage`;
10
+ export const DID_SPACE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user/did-spaces`;
11
11
  export const NAVIGATION_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/admin/navigation`;
12
12
  export const DID_PREFIX = 'did:abt:';
13
13
  export const PASSPORT_STATUS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.11.25",
3
+ "version": "2.11.27",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -68,12 +68,12 @@
68
68
  "react": ">=18.2.0",
69
69
  "react-router-dom": ">=6.22.3"
70
70
  },
71
- "gitHead": "1efa61a0f43a73a0b90654ff2db7d116782952a1",
71
+ "gitHead": "cfe12067f89f858787bcbea4822f940a2e850b76",
72
72
  "dependencies": {
73
73
  "@arcblock/did-motif": "^1.1.13",
74
- "@arcblock/icons": "^2.11.25",
75
- "@arcblock/nft-display": "^2.11.25",
76
- "@arcblock/react-hooks": "^2.11.25",
74
+ "@arcblock/icons": "^2.11.27",
75
+ "@arcblock/nft-display": "^2.11.27",
76
+ "@arcblock/react-hooks": "^2.11.27",
77
77
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
78
78
  "@fontsource/inter": "^5.0.16",
79
79
  "@fontsource/ubuntu-mono": "^5.0.18",
package/src/DID/index.tsx CHANGED
@@ -3,9 +3,9 @@ import { types } from '@ocap/mcrypto';
3
3
  import QRCode from 'qrcode.react';
4
4
  import { Icon } from '@iconify/react';
5
5
  import IconQrCode from '@iconify-icons/material-symbols/qr-code-rounded';
6
- import { Box, Dialog, DialogContent, Typography } from '@mui/material';
6
+ import { Box, Dialog, DialogContent, ModalProps, Typography } from '@mui/material';
7
7
  import { useCreation, useMemoizedFn } from 'ahooks';
8
- import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react';
8
+ import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
9
9
 
10
10
  import Address, { IDidAddressWrapper } from '../Address';
11
11
  import Avatar from '../Avatar';
@@ -15,7 +15,6 @@ import { DID_PREFIX } from '../Util/constant';
15
15
  import { HTMLDidAddressElement } from '../Address/did-address';
16
16
  import { translate } from '../Locale/util';
17
17
  import { getDIDColor, isEthereumDid } from '../Util';
18
- import type { Locale } from '../type';
19
18
 
20
19
  const translations = {
21
20
  en: {
@@ -30,28 +29,10 @@ const translations = {
30
29
  },
31
30
  };
32
31
 
33
- interface IDIDPropTypes extends IDidAddressWrapper {
34
- did: string;
35
- size?: number;
36
- component?: React.ElementType;
37
- copyable?: true | false;
38
- responsive?: true | false;
39
- showCopyButtonInTooltip?: false | true;
40
- showAvatar?: true | false;
41
- showQrcode?: false | true;
42
- inline?: false | true;
43
- append?: any;
44
- compact?: false | true;
45
- startChars?: number;
46
- endChars?: number;
47
- locale?: Locale;
48
- chainId?: string;
49
- roleType?: number;
50
- }
51
-
52
32
  const DEFAULT_CHAIN_ID = 'xenon-2020-01-15';
53
33
 
54
34
  const CHAIN_ID_MAP: Record<string, string> = {
35
+ main: DEFAULT_CHAIN_ID,
55
36
  'main.abtnetwork.io': DEFAULT_CHAIN_ID,
56
37
  'beta.abtnetwork.io': 'beta',
57
38
  };
@@ -99,14 +80,66 @@ const getAvatarSize = (didMotifInfo: any, isEthDid: boolean, size: number) => {
99
80
  return size;
100
81
  };
101
82
 
83
+ function useDIDInfo({ did, showAvatar }: { did: string; showAvatar?: boolean }) {
84
+ const isEthDid = isEthereumDid(did);
85
+ const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(did);
86
+ const content = useCreation(() => {
87
+ if (isEthDid) {
88
+ return did;
89
+ }
90
+ return `${DID_PREFIX}${did}`;
91
+ }, [did, isEthDid]);
92
+
93
+ const getPrepend = useMemoizedFn((avatarSize: number, keyPrefix: string) => [
94
+ <span
95
+ key={`${keyPrefix}-prefix-did-${avatarSize}`}
96
+ style={{ flex: '0 0 auto', color: getFontColor(did, didMotifInfo, isEthDid) }}>
97
+ DID:
98
+ </span>,
99
+ <span key={`${keyPrefix}-prefix-abt-${avatarSize}`} className="did-address-text">
100
+ {isEthDid ? 'ETH' : 'ABT'}:
101
+ </span>,
102
+ showAvatar && (
103
+ <Avatar
104
+ key={`${keyPrefix}-avatar-${avatarSize}`}
105
+ src=""
106
+ did={did}
107
+ size={getAvatarSize(didMotifInfo, isEthDid, avatarSize || 18)}
108
+ style={{ display: 'inline-flex', alignItems: 'center', marginLeft: 2, marginRight: 4 }}
109
+ blockiesPadding={false}
110
+ className="did-address-avatar"
111
+ />
112
+ ),
113
+ ]);
114
+
115
+ return {
116
+ isEthDid,
117
+ didMotifInfo,
118
+ content,
119
+ getPrepend,
120
+ };
121
+ }
122
+
123
+ interface DIDOwnProps {
124
+ did: string;
125
+ chainId?: string;
126
+ roleType?: number;
127
+ showAvatar?: true | false;
128
+ showQrcode?: false | true;
129
+ }
130
+
131
+ export interface DIDProps extends DIDOwnProps, Omit<IDidAddressWrapper, 'ref'> {}
132
+
102
133
  export interface HTMLDIDElement extends HTMLDidAddressElement {
103
134
  openQRCode: () => void;
104
135
  closeQRCode: () => void;
105
136
  }
106
137
 
107
- const DID = forwardRef<HTMLDIDElement, IDIDPropTypes>((props, ref) => {
138
+ export const DID = forwardRef<HTMLDIDElement, DIDProps>((props, ref) => {
108
139
  const {
109
140
  did,
141
+ chainId,
142
+ roleType,
110
143
  showAvatar = true,
111
144
  showQrcode = false,
112
145
  locale = 'en',
@@ -142,50 +175,9 @@ const DID = forwardRef<HTMLDIDElement, IDIDPropTypes>((props, ref) => {
142
175
  };
143
176
 
144
177
  const addressRef = useRef<any>(null);
145
-
146
- const t = useMemoizedFn((key, data = {}) => {
147
- return translate(translations, key, locale, 'en', data);
148
- });
149
-
150
- let chainId = props.chainId || '';
151
- try {
152
- if (!chainId) {
153
- const chainHostUrl = (window as any).blocklet?.CHAIN_HOST;
154
- if (chainHostUrl) {
155
- const chainHost = new URL(chainHostUrl).hostname;
156
- if (chainHost) {
157
- chainId = CHAIN_ID_MAP[chainHost];
158
- }
159
- }
160
- }
161
- } catch {
162
- console.warn('Failed to parse chainHost');
163
- }
178
+ const { content, getPrepend } = useDIDInfo({ did, showAvatar });
164
179
  const [open, setOpen] = useState(false);
165
- const isEthDid = isEthereumDid(did);
166
- const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(did);
167
180
 
168
- const getPrepend = (avatarSize: number, keyPrefix: string) => [
169
- <span
170
- key={`${keyPrefix}-prefix-did-${avatarSize}`}
171
- style={{ flex: '0 0 auto', color: getFontColor(did, didMotifInfo, isEthDid) }}>
172
- DID:
173
- </span>,
174
- <span key={`${keyPrefix}-prefix-abt-${avatarSize}`} className="did-address-text">
175
- ABT:
176
- </span>,
177
- showAvatar && (
178
- <Avatar
179
- key={`${keyPrefix}-avatar-${avatarSize}`}
180
- src=""
181
- did={did}
182
- size={getAvatarSize(didMotifInfo, isEthDid, avatarSize || 18)}
183
- style={{ display: 'inline-flex', alignItems: 'center', marginLeft: 2, marginRight: 4 }}
184
- blockiesPadding={false}
185
- className="did-address-avatar"
186
- />
187
- ),
188
- ];
189
181
  const closeQrCode = useMemoizedFn(() => {
190
182
  setOpen(false);
191
183
  });
@@ -209,41 +201,12 @@ const DID = forwardRef<HTMLDIDElement, IDIDPropTypes>((props, ref) => {
209
201
  );
210
202
  });
211
203
 
212
- const downloadUrl = useCreation(() => {
213
- if (['zh', 'en'].includes(locale)) {
214
- return `https://www.didwallet.io/${locale}`;
215
- }
216
- return 'https://www.didwallet.io/en';
217
- }, [locale]);
218
-
219
- const downloadTips = useCreation(() => {
220
- return (
221
- <>
222
- {t('downloadTips')}{' '}
223
- <Box
224
- component="a"
225
- href={downloadUrl}
226
- target="_blank"
227
- rel="noreferrer"
228
- sx={{
229
- color: colors.foregroundsFgInteractive,
230
- textDecoration: 'none',
231
- '&:hover': {
232
- textDecoration: 'underline',
233
- },
234
- }}>
235
- {t('download')}
236
- </Box>
237
- </>
238
- );
239
- }, [downloadUrl]);
240
-
241
204
  return (
242
205
  <>
243
206
  <Address
244
207
  key="address"
245
208
  locale={locale}
246
- content={`${DID_PREFIX}${did}`}
209
+ content={content}
247
210
  {...rest}
248
211
  ref={addressRef}
249
212
  prepend={getPrepend(rest.size, 'address')}
@@ -268,56 +231,155 @@ const DID = forwardRef<HTMLDIDElement, IDIDPropTypes>((props, ref) => {
268
231
  }>
269
232
  {did}
270
233
  </Address>
271
-
272
- <Dialog
234
+ <DIDDialog
235
+ did={did}
236
+ chainId={chainId}
237
+ roleType={roleType}
238
+ showAvatar={showAvatar}
273
239
  open={open}
274
240
  onClose={closeQrCode}
275
- maxWidth="sm"
276
- PaperProps={{
277
- sx: {
278
- boxShadow: 'none',
279
- borderRadius: '12px',
280
- },
281
- }}>
282
- {/* @ts-ignore */}
283
- <DialogContent align="center" sx={{ p: 3 }}>
284
- <Typography sx={{ mb: 2, fontWeight: 500, fontSize: 18 }}>
285
- {t('scanQrcode', { role: getRoleName(props.roleType || didMotifInfo?.roleType) })}
286
- </Typography>
287
- <QRCode
288
- // eslint-disable-next-line max-len
289
- value={`abt://abtwallet.io/i?did=${DID_PREFIX}${did}&action=didRecognize&chainID=${
290
- chainId || DEFAULT_CHAIN_ID
291
- }`}
292
- size={256}
293
- renderAs="svg"
294
- level="M"
295
- />
296
- <Box sx={{ mt: 1.5, textAlign: 'center' }}>
297
- <Address
298
- key="dialog-address"
299
- locale={locale}
300
- content={`${DID_PREFIX}${did}`}
301
- prepend={getPrepend(16, 'dialog')}
302
- {...rest}
303
- size={16}
304
- copyable>
305
- {did}
306
- </Address>
307
- </Box>
308
- <Typography
309
- variant="body2"
310
- sx={{
311
- color: colors.textSubtitle,
312
- fontSize: '12px',
313
- mt: 1,
314
- }}>
315
- {downloadTips}
316
- </Typography>
317
- </DialogContent>
318
- </Dialog>
241
+ {...rest}
242
+ />
319
243
  </>
320
244
  );
321
245
  });
322
246
 
247
+ export interface DIDDialogProps extends DIDProps {
248
+ // DialogProps
249
+ open: boolean;
250
+ fullScreen?: false | true;
251
+ fullWidth?: false | true;
252
+ scroll?: 'body' | 'paper';
253
+ onClose?: ModalProps['onClose'];
254
+ }
255
+ export function DIDDialog({
256
+ did,
257
+ chainId,
258
+ roleType,
259
+ showAvatar = true,
260
+ // DialogProps
261
+ open,
262
+ fullScreen = false,
263
+ fullWidth = false,
264
+ scroll = 'paper',
265
+ onClose,
266
+ // AddressProps
267
+ locale = 'en',
268
+ ...rest
269
+ }: DIDDialogProps) {
270
+ const t = useMemoizedFn((key, data = {}) => {
271
+ return translate(translations, key, locale, 'en', data);
272
+ });
273
+
274
+ const { isEthDid, content, didMotifInfo, getPrepend } = useDIDInfo({ did, showAvatar });
275
+
276
+ const downloadUrl = useCreation(() => {
277
+ if (['zh', 'en'].includes(locale)) {
278
+ return `https://www.didwallet.io/${locale}`;
279
+ }
280
+ return 'https://www.didwallet.io/en';
281
+ }, [locale]);
282
+
283
+ const downloadTips = useCreation(() => {
284
+ return (
285
+ <>
286
+ {t('downloadTips')}{' '}
287
+ <Box
288
+ component="a"
289
+ href={downloadUrl}
290
+ target="_blank"
291
+ rel="noreferrer"
292
+ sx={{
293
+ color: colors.foregroundsFgInteractive,
294
+ textDecoration: 'none',
295
+ '&:hover': {
296
+ textDecoration: 'underline',
297
+ },
298
+ }}>
299
+ {t('download')}
300
+ </Box>
301
+ </>
302
+ );
303
+ }, [downloadUrl]);
304
+
305
+ const _chainId = useCreation(() => {
306
+ if (chainId) {
307
+ return CHAIN_ID_MAP[chainId] || chainId;
308
+ }
309
+
310
+ // 以太坊 DID 使用默认chainId '1'
311
+ if (isEthDid) return '1';
312
+
313
+ // 解析 chainHost 并获取对应的chainId
314
+ try {
315
+ const chainHostUrl = (window as any).blocklet?.CHAIN_HOST;
316
+ const chainHost = new URL(chainHostUrl).hostname;
317
+ if (chainHost) {
318
+ return CHAIN_ID_MAP[chainHost] || DEFAULT_CHAIN_ID;
319
+ }
320
+ } catch (error) {
321
+ console.warn('Failed to parse chainHost:', error);
322
+ }
323
+ return DEFAULT_CHAIN_ID;
324
+ }, [isEthDid, chainId]);
325
+
326
+ const qrCodeLink = useCreation(() => {
327
+ if (isEthDid) {
328
+ return `ethereum:abtwallet.io/i?address=${content}&action=didRecognize&chainID=${_chainId}`;
329
+ }
330
+ return `abt://abtwallet.io/i?did=${content}&action=didRecognize&chainID=${_chainId}`;
331
+ }, [content, isEthDid, _chainId]);
332
+
333
+ return (
334
+ <Dialog
335
+ open={open}
336
+ onClose={onClose}
337
+ fullScreen={fullScreen}
338
+ fullWidth={fullWidth}
339
+ scroll={scroll}
340
+ maxWidth="sm"
341
+ PaperProps={{
342
+ sx: {
343
+ boxShadow: 'none',
344
+ borderRadius: '12px',
345
+ },
346
+ }}>
347
+ {/* @ts-ignore */}
348
+ <DialogContent align="center" sx={{ p: 3 }}>
349
+ <Typography sx={{ mb: 2, fontWeight: 500, fontSize: 18 }}>
350
+ {t('scanQrcode', { role: getRoleName(roleType || didMotifInfo?.roleType) })}
351
+ </Typography>
352
+ <QRCode
353
+ // eslint-disable-next-line max-len
354
+ value={qrCodeLink}
355
+ size={256}
356
+ renderAs="svg"
357
+ level="M"
358
+ />
359
+ <Box sx={{ mt: 1.5, textAlign: 'center' }}>
360
+ <Address
361
+ key="dialog-address"
362
+ locale={locale}
363
+ content={content}
364
+ prepend={getPrepend(16, 'dialog')}
365
+ {...rest}
366
+ size={16}
367
+ copyable>
368
+ {did}
369
+ </Address>
370
+ </Box>
371
+ <Typography
372
+ variant="body2"
373
+ sx={{
374
+ color: colors.textSubtitle,
375
+ fontSize: '12px',
376
+ mt: 1,
377
+ }}>
378
+ {downloadTips}
379
+ </Typography>
380
+ </DialogContent>
381
+ </Dialog>
382
+ );
383
+ }
384
+
323
385
  export default DID;
@@ -616,3 +616,5 @@ const FooterContainer = styled('div')`
616
616
  }
617
617
  }
618
618
  `;
619
+
620
+ export { TableFilterList, TableFooter };
@@ -18,7 +18,7 @@ export interface HeaderProps extends Omit<BoxProps, 'maxWidth'> {
18
18
  prepend?: React.ReactNode;
19
19
  align?: 'left' | 'right';
20
20
  maxWidth?: Breakpoint | false;
21
- homeLink?: string | ((brandContent: React.ReactNode) => React.ReactNode);
21
+ homeLink?: string | ((brandContent: React.ReactNode) => JSX.Element | null);
22
22
  }
23
23
 
24
24
  /**
@@ -9,7 +9,7 @@ export const API_DID_PREFIX = '/api/did';
9
9
 
10
10
  export const DASHBOARD_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/admin`;
11
11
  export const PROFILE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user`;
12
- export const DID_SPACE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user/settings#storage`;
12
+ export const DID_SPACE_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/user/did-spaces`;
13
13
  export const NAVIGATION_URL = `${BLOCKLET_SERVICE_PATH_PREFIX}/admin/navigation`;
14
14
 
15
15
  export const DID_PREFIX = 'did:abt:';