@arcblock/ux 2.7.15 → 2.7.16
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/Dialog/confirm.js +10 -8
- package/es/Img/index.js +7 -7
- package/es/SessionManager/account-item.js +132 -0
- package/es/SessionManager/add-account-item.js +118 -0
- package/es/SessionManager/federated-login-detecter.js +5 -7
- package/es/SessionManager/index.js +117 -244
- package/es/SessionManager/manage-accounts.js +143 -0
- package/es/SessionManager/manage-blocklet.js +62 -0
- package/es/SessionManager/menu-accordion.js +95 -0
- package/es/SessionManager/translation.js +52 -0
- package/es/SessionManager/use-accounts.js +19 -0
- package/es/SessionManager/user-info.js +139 -0
- package/es/SessionManager/user-popper.js +10 -36
- package/es/SessionManager/utils.js +2 -0
- package/es/Util/index.js +7 -0
- package/lib/Dialog/confirm.js +9 -7
- package/lib/Img/index.js +7 -7
- package/lib/SessionManager/account-item.js +140 -0
- package/lib/SessionManager/add-account-item.js +126 -0
- package/lib/SessionManager/federated-login-detecter.js +5 -7
- package/lib/SessionManager/index.js +120 -257
- package/lib/SessionManager/manage-accounts.js +155 -0
- package/lib/SessionManager/manage-blocklet.js +78 -0
- package/lib/SessionManager/menu-accordion.js +103 -0
- package/lib/SessionManager/translation.js +59 -0
- package/lib/SessionManager/use-accounts.js +25 -0
- package/lib/SessionManager/user-info.js +155 -0
- package/lib/SessionManager/user-popper.js +8 -3
- package/lib/SessionManager/utils.js +16 -0
- package/lib/Util/index.js +11 -2
- package/package.json +8 -5
- package/src/Dialog/confirm.js +9 -6
- package/src/Img/index.js +5 -5
- package/src/SessionManager/account-item.jsx +111 -0
- package/src/SessionManager/add-account-item.jsx +115 -0
- package/src/SessionManager/federated-login-detecter.jsx +3 -3
- package/src/SessionManager/index.jsx +130 -238
- package/src/SessionManager/manage-accounts.jsx +143 -0
- package/src/SessionManager/manage-blocklet.jsx +64 -0
- package/src/SessionManager/menu-accordion.jsx +87 -0
- package/src/SessionManager/translation.js +52 -0
- package/src/SessionManager/use-accounts.js +18 -0
- package/src/SessionManager/user-info.jsx +116 -0
- package/src/SessionManager/user-popper.jsx +6 -36
- package/src/SessionManager/utils.js +3 -0
- package/src/Util/index.js +8 -0
- /package/src/Avatar/{did-motif.js → did-motif.jsx} +0 -0
- /package/src/Avatar/{index.js → index.jsx} +0 -0
- /package/src/Header/{auto-hidden.js → auto-hidden.jsx} +0 -0
- /package/src/Header/{header.js → header.jsx} +0 -0
- /package/src/Header/{responsive-header.js → responsive-header.jsx} +0 -0
@@ -1,60 +1,25 @@
|
|
1
|
-
/* eslint-disable react/
|
1
|
+
/* eslint-disable react/prop-types */
|
2
2
|
/* eslint-disable react/jsx-no-bind */
|
3
|
-
import { useMemo, useRef, useState } from 'react';
|
3
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
4
4
|
import PropTypes from 'prop-types';
|
5
|
-
import { Box, IconButton, MenuList, MenuItem, SvgIcon, Button,
|
6
|
-
import SwitchProfileIcon from '@mui/icons-material/PersonOutline';
|
7
|
-
import BindWalletIcon from '@mui/icons-material/Link';
|
8
|
-
import SwitchPassportIcon from '@mui/icons-material/VpnKeyOutlined';
|
9
|
-
import ShieldCheck from 'mdi-material-ui/ShieldCheck';
|
5
|
+
import { Box, IconButton, MenuList, MenuItem, SvgIcon, Button, CircularProgress, Divider } from '@mui/material';
|
10
6
|
import AccountIcon from '@arcblock/icons/lib/Account';
|
11
|
-
import OpenInIcon from '@arcblock/icons/lib/OpenIn';
|
12
7
|
import DisconnectIcon from '@arcblock/icons/lib/Disconnect';
|
13
|
-
import SwitchDidIcon from '@arcblock/icons/lib/Switch';
|
14
|
-
import useBrowser from '@arcblock/react-hooks/lib/useBrowser';
|
15
8
|
import noop from 'lodash/noop';
|
16
9
|
import isEmpty from 'lodash/isEmpty';
|
10
|
+
import { useLatest, useMemoizedFn } from 'ahooks';
|
17
11
|
|
18
12
|
import DidAvatar from '../Avatar';
|
19
|
-
import
|
20
|
-
import { getUserAvatar } from '../Util';
|
13
|
+
import { getUserAvatar, sleep } from '../Util';
|
21
14
|
import FederatedLoginDetecter from './federated-login-detecter';
|
22
15
|
import UserPopper from './user-popper';
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
switchPassport: 'Switch Passport',
|
31
|
-
disconnect: 'Disconnect',
|
32
|
-
connect: 'Connect',
|
33
|
-
openInWallet: 'Open DID Wallet',
|
34
|
-
alreadyBindOAuth: 'Already bind Auth0',
|
35
|
-
bind: 'Bind ',
|
36
|
-
thirdParty: 'Third Party Login',
|
37
|
-
connectedWith: 'Connected with',
|
38
|
-
},
|
39
|
-
zh: {
|
40
|
-
account: '账号',
|
41
|
-
switchDid: '切换账户',
|
42
|
-
switchTo: '切换至',
|
43
|
-
switchProfile: '切换用户信息',
|
44
|
-
switchPassport: '切换通行证',
|
45
|
-
disconnect: '退出',
|
46
|
-
connect: '登录',
|
47
|
-
openInWallet: '打开 DID 钱包',
|
48
|
-
// NOTE: 目前只有 Auth0,展示出具体的第三方名字会更好
|
49
|
-
alreadyBindOAuth: '已绑定 Auth0 账号',
|
50
|
-
bind: '绑定',
|
51
|
-
thirdParty: '第三方登录',
|
52
|
-
connectedWith: '连接至',
|
53
|
-
},
|
54
|
-
};
|
55
|
-
|
56
|
-
const getConnectedAccounts = (user) => user?.connectedAccounts || user?.extraConfigs?.connectedAccounts || [];
|
57
|
-
const getSourceProvider = (user) => user?.sourceProvider || user?.extraConfigs?.sourceProvider || 'wallet';
|
16
|
+
import UserInfo from './user-info';
|
17
|
+
import { translate } from '../Locale/util';
|
18
|
+
import ManageAccounts from './manage-accounts';
|
19
|
+
import ManageBlocklet from './manage-blocklet';
|
20
|
+
import { translations } from './translation';
|
21
|
+
import { getConnectedAccounts, getSourceProvider } from './utils';
|
22
|
+
import useAccounts from './use-accounts';
|
58
23
|
|
59
24
|
function SessionManager({
|
60
25
|
session,
|
@@ -77,25 +42,26 @@ function SessionManager({
|
|
77
42
|
size,
|
78
43
|
...rest
|
79
44
|
}) {
|
80
|
-
const
|
45
|
+
const latestSession = useLatest(session);
|
46
|
+
const { connectAccount } = useAccounts();
|
47
|
+
const t = useMemoizedFn((key, data = {}) => {
|
48
|
+
return translate(translations, key, locale, 'en', data);
|
49
|
+
});
|
81
50
|
const userAnchorRef = useRef(null);
|
82
|
-
|
83
|
-
const { logoutOAuth, bindOAuth, configs: oauthConfigs, switchOAuthPassport } = session.useOAuth();
|
51
|
+
const { logoutOAuth, switchOAuthPassport } = session.useOAuth();
|
84
52
|
const [userOpen, setUserOpen] = useState(false);
|
85
53
|
|
86
54
|
// base64 img maybe have some blank char, need encodeURIComponent to transform it
|
87
55
|
const avatar = getUserAvatar(session.user?.avatar?.replace(/\s/g, encodeURIComponent(' ')));
|
88
|
-
const currentRole = useMemo(
|
89
|
-
() => session.user?.passports?.find((item) => item.name === session.user.role),
|
90
|
-
[session.user]
|
91
|
-
);
|
92
|
-
const browser = useBrowser();
|
93
|
-
// eslint-disable-next-line react/prop-types
|
94
|
-
const { walletDid } = session.useDid({ session });
|
95
56
|
|
96
57
|
const isRawWalletAccount = getSourceProvider(session.user) === 'wallet';
|
97
58
|
const connectedAccounts = getConnectedAccounts(session.user);
|
98
|
-
|
59
|
+
|
60
|
+
const isFirstLoading = useMemo(() => {
|
61
|
+
return session?.initialized === false && session?.loading === true;
|
62
|
+
}, [session?.initialized, session?.loading]);
|
63
|
+
|
64
|
+
// const federatedAccount = connectedAccounts.find((item) => item.provider === 'federated');
|
99
65
|
let hasBindWallet = false;
|
100
66
|
let hasBindAccount = false;
|
101
67
|
if (isRawWalletAccount) {
|
@@ -108,20 +74,59 @@ function SessionManager({
|
|
108
74
|
hasBindWallet = true;
|
109
75
|
}
|
110
76
|
|
111
|
-
const
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
77
|
+
const _connectAccount = useMemoizedFn(async () => {
|
78
|
+
// HACK: 强制等待组件渲染一轮,以拿到最新的 session 值
|
79
|
+
await sleep();
|
80
|
+
if (!latestSession.current?.user) {
|
81
|
+
return;
|
82
|
+
}
|
83
|
+
if (typeof window === 'undefined') {
|
84
|
+
return;
|
85
|
+
}
|
86
|
+
const blocklet = window?.blocklet;
|
87
|
+
if (!blocklet) {
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
const currentApp = {
|
91
|
+
appId: blocklet.appId,
|
92
|
+
appPid: blocklet.appPid,
|
93
|
+
appName: blocklet.appName,
|
94
|
+
appDescription: blocklet.appDescription,
|
95
|
+
appLogo: blocklet.appLogo,
|
96
|
+
appUrl: blocklet.appUrl,
|
97
|
+
version: blocklet.version,
|
98
|
+
provider: 'wallet',
|
99
|
+
};
|
100
|
+
const federatedMaster = blocklet.settings?.federated?.master;
|
101
|
+
const masterApp = isEmpty(federatedMaster)
|
102
|
+
? null
|
103
|
+
: {
|
104
|
+
appId: federatedMaster.appId,
|
105
|
+
appName: federatedMaster.appName,
|
106
|
+
appDescription: federatedMaster.appDescription,
|
107
|
+
appLogo: federatedMaster.appLogo,
|
108
|
+
appPid: federatedMaster.appPid,
|
109
|
+
appUrl: federatedMaster.appUrl,
|
110
|
+
version: federatedMaster.version,
|
111
|
+
provider: 'federated',
|
112
|
+
};
|
113
|
+
const loginAccount = {
|
114
|
+
did: latestSession.current.user.did,
|
115
|
+
avatar: latestSession.current.user.avatar,
|
116
|
+
provider: latestSession.current.provider,
|
117
|
+
...(latestSession.current.provider === 'federated' ? masterApp : currentApp),
|
118
|
+
};
|
119
|
+
connectAccount(loginAccount);
|
120
|
+
});
|
122
121
|
|
123
|
-
|
124
|
-
|
122
|
+
// HACK: 用于处理 统一登录 的自动登录情况,添加一个已连接的账号
|
123
|
+
// 同时可用于以前的站点,会自动生成一个已连接的账号
|
124
|
+
useEffect(() => {
|
125
|
+
if (session.user) {
|
126
|
+
_connectAccount();
|
127
|
+
}
|
128
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
129
|
+
}, [session.user]);
|
125
130
|
|
126
131
|
if (!session.user) {
|
127
132
|
return (
|
@@ -137,7 +142,7 @@ function SessionManager({
|
|
137
142
|
{...rest}
|
138
143
|
data-cy="sessionManager-login">
|
139
144
|
{isFirstLoading ? <CircularProgress /> : <AccountIcon />}
|
140
|
-
<span style={{ lineHeight: '25px' }}>{
|
145
|
+
<span style={{ lineHeight: '25px' }}>{t('connect')}</span>
|
141
146
|
</Button>
|
142
147
|
) : (
|
143
148
|
<IconButton
|
@@ -167,16 +172,23 @@ function SessionManager({
|
|
167
172
|
setUserOpen((prevOpen) => !prevOpen);
|
168
173
|
}
|
169
174
|
|
175
|
+
function close() {
|
176
|
+
setUserOpen(false);
|
177
|
+
}
|
178
|
+
|
170
179
|
function onCloseUser(e) {
|
171
180
|
if (userAnchorRef.current && userAnchorRef.current.contains(e.target)) {
|
172
181
|
return;
|
173
182
|
}
|
174
|
-
|
183
|
+
close();
|
175
184
|
}
|
176
185
|
|
177
186
|
function _onLogin() {
|
178
187
|
if (!isFirstLoading) {
|
179
|
-
session.login(
|
188
|
+
session.login((...args) => {
|
189
|
+
_connectAccount();
|
190
|
+
onLogin(...args);
|
191
|
+
});
|
180
192
|
}
|
181
193
|
}
|
182
194
|
function _onLogout() {
|
@@ -189,7 +201,7 @@ function SessionManager({
|
|
189
201
|
console.error(err);
|
190
202
|
})
|
191
203
|
.finally(() => {
|
192
|
-
|
204
|
+
close();
|
193
205
|
});
|
194
206
|
});
|
195
207
|
}
|
@@ -197,58 +209,27 @@ function SessionManager({
|
|
197
209
|
* @name 切换账户
|
198
210
|
* @description 该功能仅在登录后才能使用,目前仅用于切换普通登录和统一登录的账户,所以会增加一些与统一登录相关的逻辑
|
199
211
|
*/
|
200
|
-
|
201
|
-
const { provider, user } = session;
|
202
|
-
if (!user) return;
|
203
|
-
let targetProvider = provider;
|
204
|
-
if (provider === 'federated') {
|
205
|
-
targetProvider = 'wallet';
|
206
|
-
} else if (['auth0', 'wallet'].includes(provider)) {
|
207
|
-
targetProvider = 'federated';
|
208
|
-
}
|
209
|
-
session.switchDid(
|
210
|
-
(...args) => {
|
211
|
-
setUserOpen(false);
|
212
|
-
onSwitchDid(...args);
|
213
|
-
},
|
214
|
-
{
|
215
|
-
provider: targetProvider,
|
216
|
-
providerMode: 'paramsFirst',
|
217
|
-
}
|
218
|
-
);
|
219
|
-
}
|
212
|
+
|
220
213
|
function _onSwitchProfile() {
|
221
214
|
session.switchProfile((...args) => {
|
222
|
-
|
215
|
+
close();
|
223
216
|
onSwitchProfile(...args);
|
224
217
|
});
|
225
218
|
}
|
219
|
+
|
226
220
|
function _onSwitchPassport() {
|
227
221
|
const { user, provider } = session;
|
228
222
|
if (!isRawWalletAccount && provider !== 'federated') {
|
229
223
|
switchOAuthPassport(user);
|
230
224
|
} else {
|
231
|
-
|
225
|
+
close();
|
232
226
|
session.switchPassport((...args) => {
|
233
|
-
|
227
|
+
close();
|
234
228
|
onSwitchPassport(...args);
|
235
229
|
});
|
236
230
|
}
|
237
231
|
}
|
238
232
|
|
239
|
-
function _onBindWallet() {
|
240
|
-
setUserOpen(false);
|
241
|
-
// FIXME: @zhanghan 暂时切换回 isRawWalletAccount 的方式来判断,在 did-connect 改版时,简化这里的关系判断
|
242
|
-
if (!isRawWalletAccount) {
|
243
|
-
session.bindWallet((...args) => {
|
244
|
-
setUserOpen(false);
|
245
|
-
onBindWallet(...args);
|
246
|
-
});
|
247
|
-
} else {
|
248
|
-
bindOAuth();
|
249
|
-
}
|
250
|
-
}
|
251
|
-
|
252
233
|
return (
|
253
234
|
<>
|
254
235
|
<IconButton
|
@@ -265,110 +246,43 @@ function SessionManager({
|
|
265
246
|
|
266
247
|
<UserPopper open={userOpen} onClose={onCloseUser} anchorEl={userAnchorRef.current} dark={dark}>
|
267
248
|
<MenuList sx={{ p: 0 }}>
|
268
|
-
<
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
{
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
<MenuItem
|
304
|
-
key={index}
|
305
|
-
className="session-manager-menu-item"
|
306
|
-
{...{
|
307
|
-
...menuProps,
|
308
|
-
icon: undefined,
|
309
|
-
label: undefined,
|
310
|
-
}}>
|
311
|
-
{svgIcon
|
312
|
-
? svgIcon && <SvgIcon component={svgIcon} className="session-manager-menu-icon" />
|
313
|
-
: menuItem.icon}
|
314
|
-
{menuItem.label}
|
315
|
-
</MenuItem>
|
316
|
-
);
|
317
|
-
})}
|
318
|
-
{menuRender({
|
319
|
-
classes: {
|
320
|
-
menuItem: 'session-manager-menu-item',
|
321
|
-
menuIcon: 'session-manager-menu-icon',
|
322
|
-
},
|
323
|
-
})}
|
324
|
-
{!browser.wallet && (
|
325
|
-
<MenuItem
|
326
|
-
component="a"
|
327
|
-
className="session-manager-menu-item"
|
328
|
-
data-cy="sessionManager-openInWallet"
|
329
|
-
href="https://www.abtwallet.io/"
|
330
|
-
aria-label={translation.openInWallet}
|
331
|
-
target="_blank">
|
332
|
-
<SvgIcon component={OpenInIcon} className="session-manager-menu-icon" />
|
333
|
-
{translation.openInWallet}
|
334
|
-
</MenuItem>
|
335
|
-
)}
|
336
|
-
{!isEmpty(masterSiteInfo) && !!switchDid && (
|
337
|
-
<MenuItem
|
338
|
-
className="session-manager-menu-item"
|
339
|
-
onClick={_onSwitchDid}
|
340
|
-
aria-label={translation.switchDid}
|
341
|
-
data-cy="sessionManager-switch-trigger">
|
342
|
-
<SvgIcon component={SwitchDidIcon} className="session-manager-menu-icon" />
|
343
|
-
<Box sx={{ whiteSpace: 'normal', wordBreak: 'break-all' }}>
|
344
|
-
{translation.switchTo}
|
345
|
-
{session.provider === 'federated' ? (
|
346
|
-
<Link
|
347
|
-
mx={1}
|
348
|
-
href={currentSiteInfo.appUrl}
|
349
|
-
underline="hover"
|
350
|
-
target="_blank"
|
351
|
-
title={currentSiteInfo.appName}
|
352
|
-
aria-label="Open current site url">
|
353
|
-
{currentSiteInfo.appName}
|
354
|
-
</Link>
|
355
|
-
) : (
|
356
|
-
<Link
|
357
|
-
mx={1}
|
358
|
-
href={masterSiteInfo.appUrl}
|
359
|
-
underline="hover"
|
360
|
-
target="_blank"
|
361
|
-
title={masterSiteInfo.appName}
|
362
|
-
aria-label="Open federated master site url">
|
363
|
-
{masterSiteInfo.appName}
|
364
|
-
</Link>
|
365
|
-
)}
|
366
|
-
{translation.account}
|
367
|
-
</Box>
|
368
|
-
</MenuItem>
|
369
|
-
)}
|
249
|
+
<UserInfo
|
250
|
+
session={session}
|
251
|
+
size={size}
|
252
|
+
locale={locale}
|
253
|
+
onEditUser={() => {
|
254
|
+
close();
|
255
|
+
_onSwitchProfile();
|
256
|
+
}}
|
257
|
+
onSwitchPassport={() => {
|
258
|
+
close();
|
259
|
+
_onSwitchPassport();
|
260
|
+
}}
|
261
|
+
close={close}
|
262
|
+
switchProfile={switchProfile}
|
263
|
+
hasBindWallet={hasBindWallet}
|
264
|
+
/>
|
265
|
+
|
266
|
+
<Divider />
|
267
|
+
|
268
|
+
<ManageAccounts
|
269
|
+
session={session}
|
270
|
+
locale={locale}
|
271
|
+
onBindWallet={onBindWallet}
|
272
|
+
onSwitchDid={onSwitchDid}
|
273
|
+
connectAccount={_connectAccount}
|
274
|
+
close={close}
|
275
|
+
hasBindAccount={hasBindAccount}
|
276
|
+
/>
|
277
|
+
|
278
|
+
<Divider />
|
279
|
+
|
280
|
+
<ManageBlocklet menu={menu} menuRender={menuRender} locale={locale} />
|
281
|
+
|
282
|
+
<Divider />
|
283
|
+
|
370
284
|
{/* NOTE: federated 登录方式不允许切换 profile */}
|
371
|
-
{!!switchProfile && hasBindWallet && session.provider !== 'federated' && (
|
285
|
+
{/* {!!switchProfile && hasBindWallet && session.provider !== 'federated' && (
|
372
286
|
<MenuItem
|
373
287
|
className="session-manager-menu-item"
|
374
288
|
onClick={_onSwitchProfile}
|
@@ -377,29 +291,7 @@ function SessionManager({
|
|
377
291
|
<SvgIcon component={SwitchProfileIcon} className="session-manager-menu-icon" />
|
378
292
|
{translation.switchProfile}
|
379
293
|
</MenuItem>
|
380
|
-
)}
|
381
|
-
{!!switchPassport && (
|
382
|
-
<MenuItem
|
383
|
-
className="session-manager-menu-item"
|
384
|
-
onClick={_onSwitchPassport}
|
385
|
-
aria-label={translation.switchPassport}
|
386
|
-
data-cy="sessionManager-switch-passport-trigger">
|
387
|
-
<SvgIcon component={SwitchPassportIcon} className="session-manager-menu-icon" />
|
388
|
-
{translation.switchPassport}
|
389
|
-
</MenuItem>
|
390
|
-
)}
|
391
|
-
{oauthConfigList.length > 0 && !hasBindAccount && session.provider !== 'federated' && (
|
392
|
-
<MenuItem
|
393
|
-
className="session-manager-menu-item"
|
394
|
-
onClick={_onBindWallet}
|
395
|
-
aria-label={
|
396
|
-
!isRawWalletAccount ? `${translation.bind}DID Wallet` : `${translation.bind}${translation.thirdParty}`
|
397
|
-
}
|
398
|
-
data-cy="sessionManager-bind-trigger">
|
399
|
-
<SvgIcon component={BindWalletIcon} className="session-manager-menu-icon" />
|
400
|
-
{!isRawWalletAccount ? `${translation.bind}DID Wallet` : `${translation.bind}${translation.thirdParty}`}
|
401
|
-
</MenuItem>
|
402
|
-
)}
|
294
|
+
)} */}
|
403
295
|
|
404
296
|
<MenuItem
|
405
297
|
className="session-manager-menu-item"
|
@@ -408,7 +300,7 @@ function SessionManager({
|
|
408
300
|
aria-label="Logout account"
|
409
301
|
data-cy="sessionManager-logout-trigger">
|
410
302
|
<SvgIcon component={DisconnectIcon} className="session-manager-menu-icon" />
|
411
|
-
{
|
303
|
+
{t('disconnect')}
|
412
304
|
</MenuItem>
|
413
305
|
</MenuList>
|
414
306
|
</UserPopper>
|
@@ -0,0 +1,143 @@
|
|
1
|
+
/* eslint-disable react/prop-types */
|
2
|
+
/* eslint-disable react/jsx-no-bind */
|
3
|
+
import { useMemoizedFn, useUpdate } from 'ahooks';
|
4
|
+
import { MenuItem } from '@mui/material';
|
5
|
+
import { Icon } from '@iconify/react';
|
6
|
+
import AccountIcon from '@arcblock/icons/lib/Account';
|
7
|
+
import LinkIcon from '@iconify-icons/mdi/link';
|
8
|
+
|
9
|
+
import AccountItem from './account-item';
|
10
|
+
import MenuAccordion from './menu-accordion';
|
11
|
+
import { translations } from './translation';
|
12
|
+
import { translate } from '../Locale/util';
|
13
|
+
import { useConfirm } from '../Dialog/confirm';
|
14
|
+
import { getSourceProvider } from './utils';
|
15
|
+
import AddAccountItem from './add-account-item';
|
16
|
+
import useAccounts from './use-accounts';
|
17
|
+
|
18
|
+
export default function ManageAccounts({
|
19
|
+
session,
|
20
|
+
locale,
|
21
|
+
onBindWallet,
|
22
|
+
onSwitchDid,
|
23
|
+
connectAccount,
|
24
|
+
close,
|
25
|
+
hasBindAccount,
|
26
|
+
}) {
|
27
|
+
const { bindOAuth, configs: oauthConfigs } = session.useOAuth();
|
28
|
+
const t = useMemoizedFn((key, data = {}) => {
|
29
|
+
return translate(translations, key, locale, 'en', data);
|
30
|
+
});
|
31
|
+
|
32
|
+
const { confirmApi, confirmHolder } = useConfirm();
|
33
|
+
const { accounts, setAccounts } = useAccounts();
|
34
|
+
const update = useUpdate();
|
35
|
+
|
36
|
+
const onChoose = useMemoizedFn((account, { active }) => {
|
37
|
+
if (active) {
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
close();
|
41
|
+
session.switchDid(
|
42
|
+
(...args) => {
|
43
|
+
connectAccount();
|
44
|
+
onSwitchDid(...args);
|
45
|
+
},
|
46
|
+
{
|
47
|
+
provider: account.provider,
|
48
|
+
providerMode: 'paramsFirst',
|
49
|
+
}
|
50
|
+
);
|
51
|
+
});
|
52
|
+
|
53
|
+
const oauthConfigList = Object.entries(oauthConfigs)
|
54
|
+
.map(([key, value]) => {
|
55
|
+
return { ...value, provider: key };
|
56
|
+
})
|
57
|
+
.filter((item) => item.enabled);
|
58
|
+
|
59
|
+
const isRawWalletAccount = getSourceProvider(session.user) === 'wallet';
|
60
|
+
|
61
|
+
const onDelete = useMemoizedFn((account, { active }) => {
|
62
|
+
if (active) {
|
63
|
+
return;
|
64
|
+
}
|
65
|
+
confirmApi.open({
|
66
|
+
title: t('deleteAccountTitle'),
|
67
|
+
content: t('deleteAccountContent'),
|
68
|
+
confirmButtonText: t('confirm'),
|
69
|
+
cancelButtonText: t('cancel'),
|
70
|
+
onConfirm(done) {
|
71
|
+
const findIndex = accounts.findIndex((item) => item.did === account.did);
|
72
|
+
if (findIndex >= 0) {
|
73
|
+
accounts.splice(findIndex, 1);
|
74
|
+
}
|
75
|
+
setAccounts(accounts);
|
76
|
+
update();
|
77
|
+
done();
|
78
|
+
},
|
79
|
+
});
|
80
|
+
});
|
81
|
+
|
82
|
+
const onAdd = useMemoizedFn((app) => {
|
83
|
+
close();
|
84
|
+
session.switchDid(
|
85
|
+
(...args) => {
|
86
|
+
connectAccount();
|
87
|
+
update();
|
88
|
+
onSwitchDid(...args);
|
89
|
+
},
|
90
|
+
{
|
91
|
+
provider: app.provider,
|
92
|
+
providerMode: 'paramsFirst',
|
93
|
+
}
|
94
|
+
);
|
95
|
+
});
|
96
|
+
|
97
|
+
function _onBindWallet() {
|
98
|
+
close();
|
99
|
+
// FIXME: @zhanghan 暂时切换回 isRawWalletAccount 的方式来判断,在 did-connect 改版时,简化这里的关系判断
|
100
|
+
if (!isRawWalletAccount) {
|
101
|
+
session.bindWallet(onBindWallet);
|
102
|
+
} else {
|
103
|
+
bindOAuth();
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
return (
|
108
|
+
<>
|
109
|
+
<MenuAccordion
|
110
|
+
locale={locale}
|
111
|
+
title={
|
112
|
+
<>
|
113
|
+
<AccountIcon className="session-manager-menu-icon" style={{ width: 24, height: 24 }} />
|
114
|
+
{t('manageAccounts')}
|
115
|
+
</>
|
116
|
+
}>
|
117
|
+
{accounts.map((item) => (
|
118
|
+
<AccountItem
|
119
|
+
key={item.did}
|
120
|
+
account={item}
|
121
|
+
locale={locale}
|
122
|
+
active={session.user.did === item.did}
|
123
|
+
onDelete={onDelete}
|
124
|
+
onChoose={onChoose}
|
125
|
+
/>
|
126
|
+
))}
|
127
|
+
<AddAccountItem locale={locale} onAdd={onAdd} />
|
128
|
+
|
129
|
+
{oauthConfigList.length > 0 && !hasBindAccount && session.provider !== 'federated' && (
|
130
|
+
<MenuItem
|
131
|
+
className="session-manager-menu-item"
|
132
|
+
onClick={_onBindWallet}
|
133
|
+
aria-label={!isRawWalletAccount ? `${t('bind')}DID Wallet` : `${t('bind')}${t('thirdParty')}`}
|
134
|
+
data-cy="sessionManager-bind-trigger">
|
135
|
+
<Icon icon={LinkIcon} width={24} height={24} className="session-manager-menu-icon" />
|
136
|
+
{!isRawWalletAccount ? `${t('bind')}DID Wallet` : `${t('bind')}${t('thirdParty')}`}
|
137
|
+
</MenuItem>
|
138
|
+
)}
|
139
|
+
</MenuAccordion>
|
140
|
+
{confirmHolder}
|
141
|
+
</>
|
142
|
+
);
|
143
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
/* eslint-disable react/no-array-index-key */
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { useMemoizedFn } from 'ahooks';
|
4
|
+
import { Icon } from '@iconify/react';
|
5
|
+
import AppsIcon from '@iconify-icons/mdi/apps';
|
6
|
+
import { MenuItem, SvgIcon } from '@mui/material';
|
7
|
+
|
8
|
+
import MenuAccordion from './menu-accordion';
|
9
|
+
import { translate } from '../Locale/util';
|
10
|
+
import { translations } from './translation';
|
11
|
+
|
12
|
+
export default function ManageBlocklet({ menu, menuRender, locale }) {
|
13
|
+
const t = useMemoizedFn((key, data = {}) => {
|
14
|
+
return translate(translations, key, locale, 'en', data);
|
15
|
+
});
|
16
|
+
|
17
|
+
return (
|
18
|
+
<MenuAccordion
|
19
|
+
locale={locale}
|
20
|
+
title={
|
21
|
+
<>
|
22
|
+
<Icon icon={AppsIcon} width={24} height={24} className="session-manager-menu-icon" />
|
23
|
+
{t('manageBlocklet')}
|
24
|
+
</>
|
25
|
+
}>
|
26
|
+
{Array.isArray(menu) &&
|
27
|
+
menu.map((menuItem, index) => {
|
28
|
+
const { svgIcon, ...menuProps } = menuItem;
|
29
|
+
return (
|
30
|
+
<MenuItem
|
31
|
+
key={index}
|
32
|
+
className="session-manager-menu-item"
|
33
|
+
{...{
|
34
|
+
...menuProps,
|
35
|
+
icon: undefined,
|
36
|
+
label: undefined,
|
37
|
+
}}>
|
38
|
+
{svgIcon
|
39
|
+
? svgIcon && <SvgIcon component={svgIcon} className="session-manager-menu-icon" />
|
40
|
+
: menuItem.icon}
|
41
|
+
{menuItem.label}
|
42
|
+
</MenuItem>
|
43
|
+
);
|
44
|
+
})}
|
45
|
+
{menuRender({
|
46
|
+
classes: {
|
47
|
+
menuItem: 'session-manager-menu-item',
|
48
|
+
menuIcon: 'session-manager-menu-icon',
|
49
|
+
},
|
50
|
+
})}
|
51
|
+
</MenuAccordion>
|
52
|
+
);
|
53
|
+
}
|
54
|
+
|
55
|
+
ManageBlocklet.propTypes = {
|
56
|
+
menu: PropTypes.array,
|
57
|
+
menuRender: PropTypes.func,
|
58
|
+
locale: PropTypes.string.isRequired,
|
59
|
+
};
|
60
|
+
|
61
|
+
ManageBlocklet.defaultProps = {
|
62
|
+
menu: [],
|
63
|
+
menuRender: () => {},
|
64
|
+
};
|