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