@arcblock/ux 2.7.14 → 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/Locale/selector.js +9 -9
- package/es/SessionManager/account-item.js +132 -0
- package/es/SessionManager/add-account-item.js +118 -0
- package/es/SessionManager/federated-login-detecter.js +15 -9
- package/es/SessionManager/index.js +122 -224
- 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 +13 -37
- 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/Locale/selector.js +16 -17
- package/lib/SessionManager/account-item.js +140 -0
- package/lib/SessionManager/add-account-item.js +126 -0
- package/lib/SessionManager/federated-login-detecter.js +15 -9
- package/lib/SessionManager/index.js +125 -237
- 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/Locale/{selector.js → selector.jsx} +9 -10
- package/src/SessionManager/account-item.jsx +111 -0
- package/src/SessionManager/add-account-item.jsx +115 -0
- package/src/SessionManager/federated-login-detecter.jsx +14 -12
- package/src/SessionManager/index.jsx +135 -214
- 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 +9 -37
- 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
- /package/src/Locale/{context.js → context.jsx} +0 -0
@@ -1,57 +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 ConnectWithoutContactIcon from '@mui/icons-material/ConnectWithoutContact';
|
10
|
-
import ShieldCheck from 'mdi-material-ui/ShieldCheck';
|
5
|
+
import { Box, IconButton, MenuList, MenuItem, SvgIcon, Button, CircularProgress, Divider } from '@mui/material';
|
11
6
|
import AccountIcon from '@arcblock/icons/lib/Account';
|
12
|
-
import OpenInIcon from '@arcblock/icons/lib/OpenIn';
|
13
7
|
import DisconnectIcon from '@arcblock/icons/lib/Disconnect';
|
14
|
-
import SwitchDidIcon from '@arcblock/icons/lib/Switch';
|
15
|
-
import useBrowser from '@arcblock/react-hooks/lib/useBrowser';
|
16
|
-
import isEmpty from 'lodash/isEmpty';
|
17
8
|
import noop from 'lodash/noop';
|
9
|
+
import isEmpty from 'lodash/isEmpty';
|
10
|
+
import { useLatest, useMemoizedFn } from 'ahooks';
|
18
11
|
|
19
12
|
import DidAvatar from '../Avatar';
|
20
|
-
import
|
21
|
-
import { getUserAvatar } from '../Util';
|
13
|
+
import { getUserAvatar, sleep } from '../Util';
|
22
14
|
import FederatedLoginDetecter from './federated-login-detecter';
|
23
15
|
import UserPopper from './user-popper';
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
connect: 'Connect',
|
32
|
-
openInWallet: 'Open DID Wallet',
|
33
|
-
alreadyBindOAuth: 'Already bind Auth0',
|
34
|
-
bind: 'Bind ',
|
35
|
-
thirdParty: 'Third Party Login',
|
36
|
-
connectedWith: 'Connected with',
|
37
|
-
},
|
38
|
-
zh: {
|
39
|
-
switchDid: '切换账户',
|
40
|
-
switchProfile: '切换用户信息',
|
41
|
-
switchPassport: '切换通行证',
|
42
|
-
disconnect: '退出',
|
43
|
-
connect: '登录',
|
44
|
-
openInWallet: '打开 DID 钱包',
|
45
|
-
// NOTE: 目前只有 Auth0,展示出具体的第三方名字会更好
|
46
|
-
alreadyBindOAuth: '已绑定 Auth0 账号',
|
47
|
-
bind: '绑定',
|
48
|
-
thirdParty: '第三方登录',
|
49
|
-
connectedWith: '连接至',
|
50
|
-
},
|
51
|
-
};
|
52
|
-
|
53
|
-
const getConnectedAccounts = (user) => user?.connectedAccounts || user?.extraConfigs?.connectedAccounts || [];
|
54
|
-
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';
|
55
23
|
|
56
24
|
function SessionManager({
|
57
25
|
session,
|
@@ -74,25 +42,26 @@ function SessionManager({
|
|
74
42
|
size,
|
75
43
|
...rest
|
76
44
|
}) {
|
77
|
-
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
|
+
});
|
78
50
|
const userAnchorRef = useRef(null);
|
79
|
-
|
80
|
-
const { logoutOAuth, bindOAuth, configs: oauthConfigs, switchOAuthPassport } = session.useOAuth();
|
51
|
+
const { logoutOAuth, switchOAuthPassport } = session.useOAuth();
|
81
52
|
const [userOpen, setUserOpen] = useState(false);
|
82
53
|
|
83
54
|
// base64 img maybe have some blank char, need encodeURIComponent to transform it
|
84
55
|
const avatar = getUserAvatar(session.user?.avatar?.replace(/\s/g, encodeURIComponent(' ')));
|
85
|
-
const currentRole = useMemo(
|
86
|
-
() => session.user?.passports?.find((item) => item.name === session.user.role),
|
87
|
-
[session.user]
|
88
|
-
);
|
89
|
-
const browser = useBrowser();
|
90
|
-
// eslint-disable-next-line react/prop-types
|
91
|
-
const { walletDid } = session.useDid({ session });
|
92
56
|
|
93
57
|
const isRawWalletAccount = getSourceProvider(session.user) === 'wallet';
|
94
58
|
const connectedAccounts = getConnectedAccounts(session.user);
|
95
|
-
|
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');
|
96
65
|
let hasBindWallet = false;
|
97
66
|
let hasBindAccount = false;
|
98
67
|
if (isRawWalletAccount) {
|
@@ -105,19 +74,59 @@ function SessionManager({
|
|
105
74
|
hasBindWallet = true;
|
106
75
|
}
|
107
76
|
|
108
|
-
const
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
+
});
|
119
121
|
|
120
|
-
|
122
|
+
// HACK: 用于处理 统一登录 的自动登录情况,添加一个已连接的账号
|
123
|
+
// 同时可用于以前的站点,会自动生成一个已连接的账号
|
124
|
+
useEffect(() => {
|
125
|
+
if (session.user) {
|
126
|
+
_connectAccount();
|
127
|
+
}
|
128
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
129
|
+
}, [session.user]);
|
121
130
|
|
122
131
|
if (!session.user) {
|
123
132
|
return (
|
@@ -133,7 +142,7 @@ function SessionManager({
|
|
133
142
|
{...rest}
|
134
143
|
data-cy="sessionManager-login">
|
135
144
|
{isFirstLoading ? <CircularProgress /> : <AccountIcon />}
|
136
|
-
<span style={{ lineHeight: '25px' }}>{
|
145
|
+
<span style={{ lineHeight: '25px' }}>{t('connect')}</span>
|
137
146
|
</Button>
|
138
147
|
) : (
|
139
148
|
<IconButton
|
@@ -163,16 +172,23 @@ function SessionManager({
|
|
163
172
|
setUserOpen((prevOpen) => !prevOpen);
|
164
173
|
}
|
165
174
|
|
175
|
+
function close() {
|
176
|
+
setUserOpen(false);
|
177
|
+
}
|
178
|
+
|
166
179
|
function onCloseUser(e) {
|
167
180
|
if (userAnchorRef.current && userAnchorRef.current.contains(e.target)) {
|
168
181
|
return;
|
169
182
|
}
|
170
|
-
|
183
|
+
close();
|
171
184
|
}
|
172
185
|
|
173
186
|
function _onLogin() {
|
174
187
|
if (!isFirstLoading) {
|
175
|
-
session.login(
|
188
|
+
session.login((...args) => {
|
189
|
+
_connectAccount();
|
190
|
+
onLogin(...args);
|
191
|
+
});
|
176
192
|
}
|
177
193
|
}
|
178
194
|
function _onLogout() {
|
@@ -185,48 +201,35 @@ function SessionManager({
|
|
185
201
|
console.error(err);
|
186
202
|
})
|
187
203
|
.finally(() => {
|
188
|
-
|
204
|
+
close();
|
189
205
|
});
|
190
206
|
});
|
191
207
|
}
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
}
|
208
|
+
/**
|
209
|
+
* @name 切换账户
|
210
|
+
* @description 该功能仅在登录后才能使用,目前仅用于切换普通登录和统一登录的账户,所以会增加一些与统一登录相关的逻辑
|
211
|
+
*/
|
212
|
+
|
198
213
|
function _onSwitchProfile() {
|
199
214
|
session.switchProfile((...args) => {
|
200
|
-
|
215
|
+
close();
|
201
216
|
onSwitchProfile(...args);
|
202
217
|
});
|
203
218
|
}
|
219
|
+
|
204
220
|
function _onSwitchPassport() {
|
205
221
|
const { user, provider } = session;
|
206
222
|
if (!isRawWalletAccount && provider !== 'federated') {
|
207
223
|
switchOAuthPassport(user);
|
208
224
|
} else {
|
209
|
-
|
225
|
+
close();
|
210
226
|
session.switchPassport((...args) => {
|
211
|
-
|
227
|
+
close();
|
212
228
|
onSwitchPassport(...args);
|
213
229
|
});
|
214
230
|
}
|
215
231
|
}
|
216
232
|
|
217
|
-
function _onBindWallet() {
|
218
|
-
setUserOpen(false);
|
219
|
-
// FIXME: @zhanghan 暂时切换回 isRawWalletAccount 的方式来判断,在 did-connect 改版时,简化这里的关系判断
|
220
|
-
if (!isRawWalletAccount) {
|
221
|
-
session.bindWallet((...args) => {
|
222
|
-
setUserOpen(false);
|
223
|
-
onBindWallet(...args);
|
224
|
-
});
|
225
|
-
} else {
|
226
|
-
bindOAuth();
|
227
|
-
}
|
228
|
-
}
|
229
|
-
|
230
233
|
return (
|
231
234
|
<>
|
232
235
|
<IconButton
|
@@ -243,103 +246,43 @@ function SessionManager({
|
|
243
246
|
|
244
247
|
<UserPopper open={userOpen} onClose={onCloseUser} anchorEl={userAnchorRef.current} dark={dark}>
|
245
248
|
<MenuList sx={{ p: 0 }}>
|
246
|
-
<
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
{
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
{translation.connectedWith}
|
282
|
-
<Link
|
283
|
-
ml={1}
|
284
|
-
href={masterSiteInfo.appUrl}
|
285
|
-
underline="hover"
|
286
|
-
target="_blank"
|
287
|
-
title={masterSiteInfo.appName}
|
288
|
-
aria-label="Open federated master site url">
|
289
|
-
{masterSiteInfo.appName}
|
290
|
-
</Link>
|
291
|
-
</Box>
|
292
|
-
</MenuItem>
|
293
|
-
)}
|
294
|
-
{Array.isArray(menu) &&
|
295
|
-
menu.map((menuItem, index) => {
|
296
|
-
const { svgIcon, ...menuProps } = menuItem;
|
297
|
-
return (
|
298
|
-
<MenuItem
|
299
|
-
key={index}
|
300
|
-
className="session-manager-menu-item"
|
301
|
-
{...{
|
302
|
-
...menuProps,
|
303
|
-
icon: undefined,
|
304
|
-
label: undefined,
|
305
|
-
}}>
|
306
|
-
{svgIcon
|
307
|
-
? svgIcon && <SvgIcon component={svgIcon} className="session-manager-menu-icon" />
|
308
|
-
: menuItem.icon}
|
309
|
-
{menuItem.label}
|
310
|
-
</MenuItem>
|
311
|
-
);
|
312
|
-
})}
|
313
|
-
{menuRender({
|
314
|
-
classes: {
|
315
|
-
menuItem: 'session-manager-menu-item',
|
316
|
-
menuIcon: 'session-manager-menu-icon',
|
317
|
-
},
|
318
|
-
})}
|
319
|
-
{!browser.wallet && (
|
320
|
-
<MenuItem
|
321
|
-
component="a"
|
322
|
-
className="session-manager-menu-item"
|
323
|
-
data-cy="sessionManager-openInWallet"
|
324
|
-
href="https://www.abtwallet.io/"
|
325
|
-
aria-label={translation.openInWallet}
|
326
|
-
target="_blank">
|
327
|
-
<SvgIcon component={OpenInIcon} className="session-manager-menu-icon" />
|
328
|
-
{translation.openInWallet}
|
329
|
-
</MenuItem>
|
330
|
-
)}
|
331
|
-
{!!switchDid && (
|
332
|
-
<MenuItem
|
333
|
-
className="session-manager-menu-item"
|
334
|
-
onClick={_onSwitchDid}
|
335
|
-
aria-label={translation.switchDid}
|
336
|
-
data-cy="sessionManager-switch-trigger">
|
337
|
-
<SvgIcon component={SwitchDidIcon} className="session-manager-menu-icon" />
|
338
|
-
{translation.switchDid}
|
339
|
-
</MenuItem>
|
340
|
-
)}
|
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
|
+
|
341
284
|
{/* NOTE: federated 登录方式不允许切换 profile */}
|
342
|
-
{!!switchProfile && hasBindWallet && session.provider !== 'federated' && (
|
285
|
+
{/* {!!switchProfile && hasBindWallet && session.provider !== 'federated' && (
|
343
286
|
<MenuItem
|
344
287
|
className="session-manager-menu-item"
|
345
288
|
onClick={_onSwitchProfile}
|
@@ -348,29 +291,7 @@ function SessionManager({
|
|
348
291
|
<SvgIcon component={SwitchProfileIcon} className="session-manager-menu-icon" />
|
349
292
|
{translation.switchProfile}
|
350
293
|
</MenuItem>
|
351
|
-
)}
|
352
|
-
{!!switchPassport && (
|
353
|
-
<MenuItem
|
354
|
-
className="session-manager-menu-item"
|
355
|
-
onClick={_onSwitchPassport}
|
356
|
-
aria-label={translation.switchPassport}
|
357
|
-
data-cy="sessionManager-switch-passport-trigger">
|
358
|
-
<SvgIcon component={SwitchPassportIcon} className="session-manager-menu-icon" />
|
359
|
-
{translation.switchPassport}
|
360
|
-
</MenuItem>
|
361
|
-
)}
|
362
|
-
{oauthConfigList.length > 0 && !hasBindAccount && session.provider !== 'federated' && (
|
363
|
-
<MenuItem
|
364
|
-
className="session-manager-menu-item"
|
365
|
-
onClick={_onBindWallet}
|
366
|
-
aria-label={
|
367
|
-
!isRawWalletAccount ? `${translation.bind}DID Wallet` : `${translation.bind}${translation.thirdParty}`
|
368
|
-
}
|
369
|
-
data-cy="sessionManager-bind-trigger">
|
370
|
-
<SvgIcon component={BindWalletIcon} className="session-manager-menu-icon" />
|
371
|
-
{!isRawWalletAccount ? `${translation.bind}DID Wallet` : `${translation.bind}${translation.thirdParty}`}
|
372
|
-
</MenuItem>
|
373
|
-
)}
|
294
|
+
)} */}
|
374
295
|
|
375
296
|
<MenuItem
|
376
297
|
className="session-manager-menu-item"
|
@@ -379,7 +300,7 @@ function SessionManager({
|
|
379
300
|
aria-label="Logout account"
|
380
301
|
data-cy="sessionManager-logout-trigger">
|
381
302
|
<SvgIcon component={DisconnectIcon} className="session-manager-menu-icon" />
|
382
|
-
{
|
303
|
+
{t('disconnect')}
|
383
304
|
</MenuItem>
|
384
305
|
</MenuList>
|
385
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
|
+
};
|