@abtnode/ux 1.16.15-beta-ed0db59e → 1.16.15-beta-d464647a
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.
- package/es/blocklet/storage/action.js +26 -13
- package/es/blocklet/storage/backups.js +7 -14
- package/es/blocklet/storage/connect-to.js +28 -52
- package/es/blocklet/storage/connected.js +19 -110
- package/es/blocklet/storage/delete.js +2 -1
- package/es/blocklet/storage/index.js +5 -8
- package/es/blocklet/storage/item.js +52 -60
- package/es/contexts/blocklet-storage.js +199 -0
- package/es/hooks/use-backups.js +36 -17
- package/es/hooks/use-space-gateways.js +66 -0
- package/es/locales/en.js +1 -1
- package/es/locales/zh.js +1 -1
- package/lib/blocklet/storage/action.js +25 -12
- package/lib/blocklet/storage/backups.js +13 -25
- package/lib/blocklet/storage/connect-to.js +33 -62
- package/lib/blocklet/storage/connected.js +18 -113
- package/lib/blocklet/storage/delete.js +2 -1
- package/lib/blocklet/storage/index.js +5 -10
- package/lib/blocklet/storage/item.js +50 -58
- package/lib/contexts/blocklet-storage.js +209 -0
- package/lib/hooks/use-backups.js +36 -17
- package/lib/hooks/use-space-gateways.js +74 -0
- package/lib/locales/en.js +1 -1
- package/lib/locales/zh.js +1 -1
- package/package.json +16 -16
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Box, Chip, LinearProgress, Typography } from '@mui/material';
|
|
2
|
-
import React, { useEffect,
|
|
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,
|
|
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
|
|
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(
|
|
152
|
+
return hasPermissionByEndpoint(backupEndpoint);
|
|
145
153
|
}, {
|
|
146
|
-
refreshDeps: [connected,
|
|
154
|
+
refreshDeps: [connected, backupEndpoint, authorizeConnect?.open, loading]
|
|
147
155
|
});
|
|
148
156
|
const shouldDisplayConnected = connected && hasPermission;
|
|
149
|
-
const
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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 (
|
|
265
|
-
if (
|
|
250
|
+
if (backupProgress?.completed) {
|
|
251
|
+
if (backupProgress?.progress === 100) {
|
|
266
252
|
Toast.success(t('storage.spaces.backupSuccessfully'));
|
|
267
|
-
} else if (
|
|
268
|
-
Toast.error(
|
|
253
|
+
} else if (backupProgress?.progress === -1) {
|
|
254
|
+
Toast.error(backupProgress?.message);
|
|
269
255
|
}
|
|
270
256
|
setLoading(false);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
} else if (
|
|
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
|
-
}, [
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
416
|
+
value: backupProgress?.progress
|
|
427
417
|
})
|
|
428
418
|
}), /*#__PURE__*/_jsx(Box, {
|
|
429
419
|
sx: {
|
|
430
|
-
|
|
420
|
+
maxWidth: '100%'
|
|
431
421
|
},
|
|
432
422
|
children: /*#__PURE__*/_jsxs(Typography, {
|
|
433
423
|
variant: "body2",
|
|
434
424
|
color: "text.secondary",
|
|
435
|
-
children: [
|
|
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:
|
|
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 };
|
package/es/hooks/use-backups.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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 {{
|
|
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
|
-
|
|
14
|
-
|
|
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 =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
const fetchBackups = debounce(async () => {
|
|
32
|
+
try {
|
|
33
|
+
setLoading(true);
|
|
34
|
+
if (!blocklet) {
|
|
35
|
+
setBackups([]);
|
|
36
|
+
return;
|
|
30
37
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
|
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: '
|
|
1373
|
+
success: 'Connected successfully'
|
|
1374
1374
|
},
|
|
1375
1375
|
backup: {
|
|
1376
1376
|
title: 'Backup',
|
package/es/locales/zh.js
CHANGED
|
@@ -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
|
-
*
|
|
25
|
-
* enableSwitchToSpace:
|
|
26
|
-
* connected:
|
|
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
|
|
64
|
-
|
|
65
|
-
|
|
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)(
|
|
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:
|
|
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,
|