@abtnode/ux 1.16.15-beta-ed0db59e → 1.16.15-beta-324519fc

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,5 +1,5 @@
1
- import { Box, Chip, LinearProgress, Typography } from '@mui/material';
2
- import React, { useEffect, useMemo, useState } from 'react';
1
+ import { Box, Chip, LinearProgress, Typography, useMediaQuery } from '@mui/material';
2
+ import React, { useEffect, useState } from 'react';
3
3
  import Button from '@arcblock/ux/lib/Button';
4
4
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
5
5
  import PropTypes from 'prop-types';
@@ -55,8 +55,9 @@ import { axios } from '../../util/api';
55
55
  import { useNodeContext } from '../../contexts/node';
56
56
  import { useBlockletContext } from '../../contexts/blocklet';
57
57
  import useBlockletInfoForConnectDIDSpaces from '../../hooks/use-blocklet-info-for-connect-did-spaces';
58
- import { getDIDSpaceDidFromEndpoint, getSpaceBackupEndpoint, getSpaceNftDisplayUrlFromEndpoint, hasPermissionByEndpoint } from '../../util/spaces';
58
+ import { getDIDSpaceDidFromEndpoint, getSpaceNftDisplayUrlFromEndpoint, hasPermissionByEndpoint } from '../../util/spaces';
59
59
  import PreviewSpaceNft from './preview-nft';
60
+ import { useBlockletStorageContext } from '../../contexts/blocklet-storage';
60
61
 
61
62
  /**
62
63
  * @description
@@ -66,7 +67,6 @@ import PreviewSpaceNft from './preview-nft';
66
67
  * progress: any,
67
68
  * onDelete: (spaceGateway: import('./connected').SpaceGateway) => Promise<void>,
68
69
  * onBackupNow: () => Promise<void>,
69
- * refreshSpaceGateways: () => void
70
70
  * }} { spaceGateway }
71
71
  */
72
72
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -75,17 +75,15 @@ import { jsxs as _jsxs } from "react/jsx-runtime";
75
75
  function SpaceItem({
76
76
  spaceGateway,
77
77
  connected,
78
- progress,
79
78
  onDelete,
80
79
  onBackupNow,
81
- refreshSpaceGateways,
82
80
  ...rest
83
81
  }) {
82
+ const isMobile = useMediaQuery(theme => theme.breakpoints.down('md'));
84
83
  const {
85
84
  t,
86
85
  locale
87
86
  } = useLocaleContext();
88
- const [loading, setLoading] = useState(false);
89
87
  /** @type {{ blocklet: import('@abtnode/client').BlockletState }} */
90
88
  const {
91
89
  blocklet
@@ -106,7 +104,17 @@ function SpaceItem({
106
104
  } = useBlockletInfoForConnectDIDSpaces({
107
105
  blocklet
108
106
  });
109
- const spaceBackupEndpoint = useMemo(() => getSpaceBackupEndpoint(blocklet?.environments), [blocklet]);
107
+ const {
108
+ updateSpaceGateway,
109
+ backupEndpoint,
110
+ backupProgress
111
+ } = useBlockletStorageContext();
112
+
113
+ // TEST:
114
+ const [loading, setLoading] = useState(false);
115
+ // backupProgress.message = '(12/99)备份到备份到备份到备份到备';
116
+ // backupProgress.progress = 99;
117
+
110
118
  const [authorizeConnect, setAuthorizeConnect] = useState({
111
119
  open: false,
112
120
  action: 'one-click-authorization',
@@ -141,12 +149,12 @@ function SpaceItem({
141
149
  if (!connected) {
142
150
  return true;
143
151
  }
144
- return hasPermissionByEndpoint(spaceBackupEndpoint);
152
+ return hasPermissionByEndpoint(backupEndpoint);
145
153
  }, {
146
- refreshDeps: [connected, spaceBackupEndpoint, authorizeConnect?.open, loading]
154
+ refreshDeps: [connected, backupEndpoint, authorizeConnect?.open, loading]
147
155
  });
148
156
  const shouldDisplayConnected = connected && hasPermission;
149
- const shouldDisplayBackupStrategy = connected && !loading && hasPermission;
157
+ const shouldDisplayBackupButton = connected && !loading && hasPermission && !spaceGateway?.loading;
150
158
  const shouldDisplayBackupProgress = connected && loading && hasPermission;
151
159
  const shouldDisplayReconnectNow = connected && !hasPermission && !hasPermissionLoading && !loading;
152
160
 
@@ -212,39 +220,17 @@ function SpaceItem({
212
220
  }));
213
221
  return;
214
222
  }
215
- await nodeApi.updateBlockletSpaceGateway({
216
- input: {
217
- did: blocklet.meta.did,
218
- where: {
219
- url: spaceGateway?.url
220
- },
221
- spaceGateway: {
222
- ...spaceGateway,
223
- name: space.name ?? 'DID Space',
224
- did: space.did ?? getDIDSpaceDidFromEndpoint(endpoint),
225
- endpoint
226
- }
227
- }
228
- });
229
- if (spaceBackupEndpoint !== endpoint) {
230
- await nodeApi.configBlocklet({
231
- input: {
232
- did: [blocklet.meta.did],
233
- configs: [{
234
- key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_BACKUP_ENDPOINT,
235
- value: endpoint
236
- }]
237
- }
238
- });
239
- }
240
- Toast.success(t('storage.spaces.connectedWithName', {
241
- name: spaceGateway?.name ?? 'DID Spaces'
242
- }));
223
+ const newSpaceGateway = {
224
+ ...spaceGateway,
225
+ name: space.name ?? 'DID Space',
226
+ did: space.did ?? getDIDSpaceDidFromEndpoint(endpoint),
227
+ endpoint
228
+ };
229
+ await updateSpaceGateway(newSpaceGateway);
243
230
  setAuthorizeConnect(preValue => ({
244
231
  ...preValue,
245
232
  open: false
246
233
  }));
247
- refreshSpaceGateways();
248
234
  };
249
235
  const _onBackupNow = async () => {
250
236
  try {
@@ -261,20 +247,20 @@ function SpaceItem({
261
247
  }
262
248
  };
263
249
  useEffect(() => {
264
- if (progress?.completed) {
265
- if (progress?.progress === 100) {
250
+ if (backupProgress?.completed) {
251
+ if (backupProgress?.progress === 100) {
266
252
  Toast.success(t('storage.spaces.backupSuccessfully'));
267
- } else if (progress?.progress === -1) {
268
- Toast.error(progress?.message);
253
+ } else if (backupProgress?.progress === -1) {
254
+ Toast.error(backupProgress?.message);
269
255
  }
270
256
  setLoading(false);
271
- progress.progress = 0;
272
- progress.message = '';
273
- } else if (progress.progress) {
257
+ backupProgress.progress = 0;
258
+ backupProgress.message = '';
259
+ } else if (backupProgress.progress) {
274
260
  setLoading(true);
275
261
  }
276
262
  // eslint-disable-next-line react-hooks/exhaustive-deps
277
- }, [progress]);
263
+ }, [backupProgress]);
278
264
  return /*#__PURE__*/_jsxs(BoxContainer, {
279
265
  style: {
280
266
  position: 'relative'
@@ -299,7 +285,8 @@ function SpaceItem({
299
285
  }), /*#__PURE__*/_jsxs(Box, {
300
286
  className: "spaces-info",
301
287
  display: "flex",
302
- flexGrow: 1,
288
+ flexGrow: (!isMobile || !shouldDisplayBackupProgress) && 1,
289
+ minWidth: "180px",
303
290
  flexDirection: shouldDisplayBackupProgress ? 'row' : 'column',
304
291
  sx: {
305
292
  marginLeft: '20px',
@@ -369,7 +356,8 @@ function SpaceItem({
369
356
  className: "spaces-backup",
370
357
  display: "flex",
371
358
  alignItems: "center",
372
- children: [shouldDisplayBackupStrategy && /*#__PURE__*/_jsxs(Box, {
359
+ flex: isMobile && shouldDisplayBackupProgress && 1,
360
+ children: [shouldDisplayBackupButton && /*#__PURE__*/_jsxs(Box, {
373
361
  className: "backup-strategy",
374
362
  display: "flex",
375
363
  alignItems: "center",
@@ -403,12 +391,14 @@ function SpaceItem({
403
391
  display: "flex",
404
392
  flexDirection: "column",
405
393
  alignItems: "center",
406
- minWidth: "640px",
394
+ minWidth: !isMobile && '640px',
395
+ marginLeft: isMobile && '16px',
396
+ width: isMobile && '360px',
407
397
  marginRight: "auto",
408
- alignSelf: "end",
398
+ alignSelf: "flex-end",
409
399
  children: [/*#__PURE__*/_jsx(Typography, {
410
400
  color: "primary",
411
- children: progress?.message
401
+ children: backupProgress?.message
412
402
  }), /*#__PURE__*/_jsxs(Box, {
413
403
  sx: {
414
404
  display: 'flex',
@@ -423,16 +413,16 @@ function SpaceItem({
423
413
  children: /*#__PURE__*/_jsx(LinearProgress, {
424
414
  color: "primary",
425
415
  variant: "determinate",
426
- value: progress?.progress
416
+ value: backupProgress?.progress
427
417
  })
428
418
  }), /*#__PURE__*/_jsx(Box, {
429
419
  sx: {
430
- minWidth: 35
420
+ maxWidth: '100%'
431
421
  },
432
422
  children: /*#__PURE__*/_jsxs(Typography, {
433
423
  variant: "body2",
434
424
  color: "text.secondary",
435
- children: [progress?.progress, "%"]
425
+ children: [backupProgress?.progress, "%"]
436
426
  })
437
427
  })]
438
428
  })]
@@ -451,13 +441,15 @@ function SpaceItem({
451
441
  }), /*#__PURE__*/_jsx(SpaceItemAction, {
452
442
  sx: {
453
443
  marginLeft: '16px',
454
- marginRight: '16px'
444
+ marginRight: '16px',
445
+ alignItems: 'flex-end',
446
+ justifyItems: 'flex-end'
455
447
  },
456
448
  spaceGateway: spaceGateway,
457
449
  connected: connected,
458
450
  onDelete: onDelete,
459
451
  onConnect: onConnect,
460
- enableSwitchToSpace: progress?.completed || isEmpty(progress?.message)
452
+ enableSwitchToSpace: backupProgress?.completed || isEmpty(backupProgress?.message)
461
453
  })]
462
454
  })]
463
455
  }), /*#__PURE__*/_jsx(DidConnect, {
@@ -489,11 +481,11 @@ SpaceItem.propTypes = {
489
481
  name: PropTypes.string.isRequired,
490
482
  url: PropTypes.string.isRequired,
491
483
  endpoint: PropTypes.string.isRequired,
492
- protected: PropTypes.bool
484
+ protected: PropTypes.bool,
485
+ loading: PropTypes.bool
493
486
  }).isRequired,
494
487
  connected: PropTypes.bool.isRequired,
495
488
  progress: PropTypes.any.isRequired,
496
- refreshSpaceGateways: PropTypes.func.isRequired,
497
489
  onDelete: PropTypes.func,
498
490
  onBackupNow: PropTypes.func
499
491
  };
@@ -0,0 +1,199 @@
1
+ import { createContext, useContext, useMemo, useState } from 'react';
2
+ import propTypes from 'prop-types';
3
+ import toast from '@arcblock/ux/lib/Toast';
4
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
5
+ import { BLOCKLET_CONFIGURABLE_KEY } from '@blocklet/constant';
6
+ import { useBlockletContext } from './blocklet';
7
+ import { getSpaceBackupEndpoint } from '../util/spaces';
8
+ import useSpaceGateways from '../hooks/use-space-gateways';
9
+ import { useNodeContext } from './node';
10
+ import useBackupProgress from '../hooks/use-backup-progress';
11
+ import useBackups from '../hooks/use-backups';
12
+
13
+ /**
14
+ * @typedef {import('../blocklet/storage/connected').SpaceGateway} SpaceGateway
15
+ * @typedef {import('@abtnode/client').Backup} Backup
16
+ */
17
+
18
+ /**
19
+ * @typedef {{
20
+ * spaceGateways: SpaceGateway[],
21
+ * selectedGateway: SpaceGateway,
22
+ * addSpaceGateway: (spaceGateway: SpaceGateway) => Promise<void>,
23
+ * deleteSpaceGateway: (spaceGateway: SpaceGateway) => Promise<void>,
24
+ * updateSpaceGateway: (spaceGateway: SpaceGateway) => Promise<void>,
25
+ * refreshSpaceGateways: () => void,
26
+ * spaceGatewaysLoading: boolean,
27
+ * spaceGatewayIsSelected: (spaceGateway: SpaceGateway) => boolean,
28
+ *
29
+ * backupEndpoint: string,
30
+ * backupProgress: any,
31
+ * backups: Backup[],
32
+ * backupsLoading: boolean,
33
+ * }} BlockletStorageContextType
34
+ */
35
+
36
+ /** @type {import('react').Context<BlockletStorageContextType>} */
37
+ import { jsx as _jsx } from "react/jsx-runtime";
38
+ const BlockletStorageContext = /*#__PURE__*/createContext({});
39
+ const {
40
+ Provider,
41
+ Consumer
42
+ } = BlockletStorageContext;
43
+ function BlockletStorageProvider({
44
+ children
45
+ }) {
46
+ const {
47
+ t
48
+ } = useLocaleContext();
49
+ /** @type {{ api: import('@abtnode/client') }} */
50
+ const {
51
+ api
52
+ } = useNodeContext();
53
+ /** @type {{ blocklet: import('@abtnode/client').BlockletState }} */
54
+ const {
55
+ blocklet
56
+ } = useBlockletContext();
57
+ const [spaceGatewaysLoading, setSpaceGatewaysLoading] = useState(false);
58
+ const [spaceGatewaysRefresh, setSpaceGatewaysRefresh] = useState(false);
59
+ const {
60
+ spaceGateways
61
+ } = useSpaceGateways({
62
+ refresh: spaceGatewaysRefresh,
63
+ setLoading: setSpaceGatewaysLoading
64
+ });
65
+ const backupProgress = useBackupProgress({
66
+ appDid: blocklet?.appDid
67
+ });
68
+ const backupEndpoint = useMemo(() => getSpaceBackupEndpoint(blocklet?.environments),
69
+ // eslint-disable-next-line react-hooks/exhaustive-deps
70
+ [blocklet, spaceGatewaysRefresh]);
71
+ const [backupsLoading, setBackupsLoading] = useState(false);
72
+ const {
73
+ backups
74
+ } = useBackups({
75
+ deps: [backupProgress],
76
+ setLoading: setBackupsLoading
77
+ });
78
+ const [selectedSpaceGateway, setSelectedSpaceGateway] = useState(spaceGateways?.find(x => x.endpoint === backupEndpoint));
79
+
80
+ /**
81
+ * @description
82
+ * @param {SpaceGateway} spaceGateway
83
+ * @param {string} endpoint
84
+ *
85
+ */
86
+ const addSpaceGateway = async (spaceGateway, endpoint) => {
87
+ spaceGateways.push({
88
+ ...spaceGateway,
89
+ loading: true
90
+ });
91
+ await api.addBlockletSpaceGateway({
92
+ input: {
93
+ did: blocklet.meta.did,
94
+ spaceGateway
95
+ }
96
+ });
97
+ if (backupEndpoint !== endpoint) {
98
+ await api.configBlocklet({
99
+ input: {
100
+ did: [blocklet.meta.did],
101
+ configs: [{
102
+ key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_BACKUP_ENDPOINT,
103
+ value: endpoint
104
+ }]
105
+ }
106
+ });
107
+ }
108
+ refreshSpaceGateways();
109
+ setSelectedSpaceGateway(spaceGateway);
110
+ };
111
+
112
+ /**
113
+ * @description
114
+ * @param {SpaceGateway} spaceGateway
115
+ */
116
+ const deleteSpaceGateway = async spaceGateway => {
117
+ if (!spaceGateway) {
118
+ return;
119
+ }
120
+ if (spaceGateway.endpoint === backupEndpoint) {
121
+ toast.warning(t('storage.spaces.gateway.delete.failedForConnected'));
122
+ return;
123
+ }
124
+ await api.deleteBlockletSpaceGateway({
125
+ input: {
126
+ did: blocklet.meta.did,
127
+ spaceGatewayDid: spaceGateway?.did
128
+ }
129
+ });
130
+ refreshSpaceGateways();
131
+ setSelectedSpaceGateway(spaceGateway);
132
+ };
133
+
134
+ /**
135
+ * @description
136
+ * @param {SpaceGateway} spaceGateway
137
+ */
138
+ const updateSpaceGateway = async spaceGateway => {
139
+ await api.updateBlockletSpaceGateway({
140
+ input: {
141
+ did: blocklet.meta.did,
142
+ where: {
143
+ url: spaceGateway.url
144
+ },
145
+ spaceGateway
146
+ }
147
+ });
148
+ if (backupEndpoint !== spaceGateway.endpoint) {
149
+ await api.configBlocklet({
150
+ input: {
151
+ did: [blocklet.meta.did],
152
+ configs: [{
153
+ key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_BACKUP_ENDPOINT,
154
+ value: spaceGateway.endpoint
155
+ }]
156
+ }
157
+ });
158
+ }
159
+ toast.success(t('storage.spaces.connectedWithName', {
160
+ name: spaceGateway?.name ?? 'DID Spaces'
161
+ }));
162
+ refreshSpaceGateways();
163
+ };
164
+ const refreshSpaceGateways = () => {
165
+ setSpaceGatewaysRefresh(p => !p);
166
+ };
167
+
168
+ /**
169
+ * @description
170
+ * @param {SpaceGateway} spaceGateway
171
+ */
172
+ const spaceGatewayIsSelected = spaceGateway => spaceGateway?.endpoint === backupEndpoint;
173
+ return /*#__PURE__*/_jsx(Provider, {
174
+ value: {
175
+ spaceGateways,
176
+ selectedSpaceGateway,
177
+ addSpaceGateway,
178
+ deleteSpaceGateway,
179
+ updateSpaceGateway,
180
+ refreshSpaceGateways,
181
+ spaceGatewaysLoading,
182
+ spaceGatewayIsSelected,
183
+ backupEndpoint,
184
+ backupProgress,
185
+ backups,
186
+ backupsLoading
187
+ },
188
+ children: children
189
+ });
190
+ }
191
+ BlockletStorageProvider.propTypes = {
192
+ children: propTypes.any.isRequired
193
+ };
194
+ BlockletStorageProvider.defaultProps = {};
195
+ function useBlockletStorageContext() {
196
+ const res = useContext(BlockletStorageContext);
197
+ return res;
198
+ }
199
+ export { BlockletStorageContext, BlockletStorageProvider, Consumer as BlockletStorageConsumer, useBlockletStorageContext };
@@ -1,18 +1,24 @@
1
- import { useCallback, useState } from 'react';
2
- import { throttle } from 'lodash';
1
+ import { useState } from 'react';
2
+ import { debounce } from 'lodash';
3
3
  import { useAsyncEffect } from 'ahooks';
4
+ import toast from '@arcblock/ux/lib/Toast';
4
5
  import { useNodeContext } from '../contexts/node';
5
6
  import { useBlockletContext } from '../contexts/blocklet';
7
+ import { formatError } from '../util';
6
8
 
7
9
  /**
8
10
  * @description
9
- * @param {{ blocklet: import('@abtnode/client').BlockletState, progress: Object, loading: boolean, }} { blocklet, progress, loading }
10
- * @return {{backups: import('@abtnode/client').Backup[]}}
11
+ * @param {{ deps: any[], setLoading: (bool: boolean) => void }} { deps }
12
+ * @return {{ backups: import('@abtnode/client').Backup[] }}
11
13
  */
12
14
  export default function useBackups({
13
- loading,
14
- progress
15
- } = {}) {
15
+ deps,
16
+ setLoading
17
+ } = {
18
+ deps: [],
19
+ setLoading: () => undefined
20
+ }) {
21
+ /** @type {{ blocklet: import('@abtnode/client').BlockletState }} */
16
22
  const {
17
23
  blocklet
18
24
  } = useBlockletContext();
@@ -20,22 +26,35 @@ export default function useBackups({
20
26
  const {
21
27
  api
22
28
  } = useNodeContext();
29
+
23
30
  // eslint-disable-next-line react-hooks/exhaustive-deps
24
- const fetchBackups = useCallback(throttle(async () => {
25
- const {
26
- backups: data
27
- } = await api.getBlockletBackups({
28
- input: {
29
- did: blocklet?.meta?.did
31
+ const fetchBackups = debounce(async () => {
32
+ try {
33
+ setLoading(true);
34
+ if (!blocklet) {
35
+ setBackups([]);
36
+ return;
30
37
  }
31
- });
32
- setBackups(data ?? []);
33
- }, 2000), []);
38
+ const {
39
+ backups: data
40
+ } = await api.getBlockletBackups({
41
+ input: {
42
+ did: blocklet.meta.did
43
+ }
44
+ });
45
+ setBackups(data ?? []);
46
+ } catch (error) {
47
+ console.error(error);
48
+ toast.error(formatError(error));
49
+ } finally {
50
+ setLoading(false);
51
+ }
52
+ }, 2000);
34
53
 
35
54
  // eslint-disable-next-line require-await
36
55
  useAsyncEffect(async () => {
37
56
  fetchBackups();
38
- }, [blocklet?.meta?.did, progress, loading]);
57
+ }, [blocklet?.meta?.did].concat(deps));
39
58
  return {
40
59
  backups
41
60
  };
@@ -0,0 +1,66 @@
1
+ import { useState } from 'react';
2
+ import { useAsyncEffect } from 'ahooks';
3
+ import toast from '@arcblock/ux/lib/Toast';
4
+ import { useNodeContext } from '../contexts/node';
5
+ import { updateSpaceGatewaysFromDIDSpaces } from '../util/space-gateway';
6
+ import { formatError } from '../../lib/util';
7
+ import { useBlockletContext } from '../contexts/blocklet';
8
+
9
+ /**
10
+ * @description
11
+ * @param {{
12
+ * blockletDid: string,
13
+ * setLoading: (bool: boolean) => void,
14
+ * refresh: boolean,
15
+ * }} { blockletDid, setLoading = () => undefined, refreshBlocklet }
16
+ * @return {{
17
+ * spaceGateways: Array<import('../contexts/blocklet-storage').SpaceGateway>
18
+ * }} {spaceGateways}
19
+ */
20
+ export default function useSpaceGateways({
21
+ setLoading,
22
+ refresh
23
+ } = {}) {
24
+ /** @type {{ blocklet: import('@abtnode/client').BlockletState }} */
25
+ const {
26
+ blocklet,
27
+ actions: {
28
+ refreshBlocklet
29
+ }
30
+ } = useBlockletContext();
31
+ const blockletDid = blocklet?.meta?.did;
32
+ const [spaceGateways, setSpaceGateways] = useState([]);
33
+ const {
34
+ api
35
+ } = useNodeContext();
36
+ useAsyncEffect(async () => {
37
+ try {
38
+ if (!blockletDid) {
39
+ setSpaceGateways([]);
40
+ return;
41
+ }
42
+ setLoading?.(true);
43
+ const {
44
+ spaceGateways: _spaceGateways
45
+ } = await api.getBlockletSpaceGateways({
46
+ input: {
47
+ did: blockletDid
48
+ }
49
+ });
50
+ const latestSpaceGateways = await updateSpaceGatewaysFromDIDSpaces({
51
+ blockletDid,
52
+ nodeApi: api,
53
+ spaceGateways: _spaceGateways
54
+ });
55
+ setSpaceGateways(latestSpaceGateways ?? []);
56
+ } catch (error) {
57
+ console.error(error);
58
+ toast.error(formatError(error));
59
+ } finally {
60
+ setLoading?.(false);
61
+ }
62
+ }, [blockletDid, refreshBlocklet, refresh]);
63
+ return {
64
+ spaceGateways
65
+ };
66
+ }
package/es/locales/en.js CHANGED
@@ -1370,7 +1370,7 @@ module.exports = {
1370
1370
  provideNFT: {
1371
1371
  title: 'Please show the DID Spaces NFT for {appName}',
1372
1372
  scan: 'Use your DID Wallet to scan the QR code below to allow the app {appName} show DID space NFT',
1373
- success: 'Operation successfully'
1373
+ success: 'Connected successfully'
1374
1374
  },
1375
1375
  backup: {
1376
1376
  title: 'Backup',
package/es/locales/zh.js CHANGED
@@ -1374,7 +1374,7 @@ module.exports = {
1374
1374
  provideNFT: {
1375
1375
  title: '请为 {appName} 出示 DID Spaces NFT',
1376
1376
  scan: '使用你的 DID Wallet 扫描下面的二维码为应用 {appName} 出示 DID Spaces NFT',
1377
- success: '操作成功'
1377
+ success: '连接成功'
1378
1378
  },
1379
1379
  backup: {
1380
1380
  title: '备份',
@@ -12,6 +12,7 @@ var _ArrowOutward = _interopRequireDefault(require("@mui/icons-material/ArrowOut
12
12
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
  var _ElectricBoltOutlined = _interopRequireDefault(require("@mui/icons-material/ElectricBoltOutlined"));
14
14
  var _FolderOutlined = _interopRequireDefault(require("@mui/icons-material/FolderOutlined"));
15
+ var _Toast = _interopRequireDefault(require("@arcblock/ux/lib/Toast"));
15
16
  var _spaces = require("../../util/spaces");
16
17
  var _delete = _interopRequireDefault(require("./delete"));
17
18
  var _jsxRuntime = require("react/jsx-runtime");
@@ -20,12 +21,12 @@ const _excluded = ["spaceGateway", "connected", "onDelete", "onConnect", "enable
20
21
  * @description
21
22
  * @param {{
22
23
  * spaceGateway: import('./connected').SpaceGateway,
23
- * onDelete: (import('./connected').SpaceGateway) => Promise<void>,
24
- * onDelete: (import('./connected').SpaceGateway) => Promise<void>,
25
- * enableSwitchToSpace: boolean,
26
- * connected: boolean
27
- * }} { spaceGateway, onDelete, ...rest }
28
- * @return {*}
24
+ * onDelete: (spaceGateway: import('./connected').SpaceGateway) => Promise<void>,
25
+ * onConnect: (spaceGateway: import('./connected').SpaceGateway) => Promise<void>,
26
+ * enableSwitchToSpace: true | false,
27
+ * connected: false | true
28
+ * } & import('@mui/material').IconButtonProps} { spaceGateway, onDelete, onConnect, enableSwitchToSpace, connected, ...rest }
29
+ * @return {React.Component}
29
30
  */
30
31
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
32
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -50,6 +51,7 @@ function SpaceItemAction(_ref) {
50
51
  const {
51
52
  t
52
53
  } = (0, _context.useLocaleContext)();
54
+ const [loading, setLoading] = (0, _react.useState)(false);
53
55
 
54
56
  /**
55
57
  * @description
@@ -60,9 +62,17 @@ function SpaceItemAction(_ref) {
60
62
  event.preventDefault();
61
63
  setAnchorEl(open && event.currentTarget);
62
64
  };
63
- const handleOnConnect = async e => {
64
- handleOpen(e, false);
65
- await onConnect(spaceGateway);
65
+ const handleOnSwitchSpace = async e => {
66
+ try {
67
+ setLoading(true);
68
+ handleOpen(e, false);
69
+ await onConnect(spaceGateway);
70
+ } catch (error) {
71
+ console.error(error);
72
+ _Toast.default.error(error.message);
73
+ } finally {
74
+ setLoading(false);
75
+ }
66
76
  };
67
77
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
68
78
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.IconButton, _objectSpread(_objectSpread({
@@ -73,7 +83,9 @@ function SpaceItemAction(_ref) {
73
83
  onClick: e => handleOpen(e, true),
74
84
  size: "small"
75
85
  }, rest), {}, {
76
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MoreVert.default, {})
86
+ children: loading || spaceGateway !== null && spaceGateway !== void 0 && spaceGateway.loading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.CircularProgress, {
87
+ size: "24px"
88
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_MoreVert.default, {})
77
89
  })), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Menu, {
78
90
  id: "simple-menu",
79
91
  anchorEl: anchorEl,
@@ -111,7 +123,7 @@ function SpaceItemAction(_ref) {
111
123
  children: t('storage.spaces.strategy.viewBackupFiles')
112
124
  })]
113
125
  }), !connected && enableSwitchToSpace && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
114
- onClick: handleOnConnect,
126
+ onClick: handleOnSwitchSpace,
115
127
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.ListItemIcon, {
116
128
  style: {
117
129
  minWidth: 24
@@ -134,7 +146,8 @@ SpaceItemAction.propTypes = {
134
146
  name: _propTypes.default.string.isRequired,
135
147
  url: _propTypes.default.string.isRequired,
136
148
  protected: _propTypes.default.bool,
137
- endpoint: _propTypes.default.string.isRequired
149
+ endpoint: _propTypes.default.string.isRequired,
150
+ loading: _propTypes.default.bool
138
151
  }).isRequired,
139
152
  connected: _propTypes.default.bool.isRequired,
140
153
  enableSwitchToSpace: _propTypes.default.bool,