@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.
Files changed (55) hide show
  1. package/es/Dialog/confirm.js +10 -8
  2. package/es/Img/index.js +7 -7
  3. package/es/Locale/selector.js +9 -9
  4. package/es/SessionManager/account-item.js +132 -0
  5. package/es/SessionManager/add-account-item.js +118 -0
  6. package/es/SessionManager/federated-login-detecter.js +15 -9
  7. package/es/SessionManager/index.js +122 -224
  8. package/es/SessionManager/manage-accounts.js +143 -0
  9. package/es/SessionManager/manage-blocklet.js +62 -0
  10. package/es/SessionManager/menu-accordion.js +95 -0
  11. package/es/SessionManager/translation.js +52 -0
  12. package/es/SessionManager/use-accounts.js +19 -0
  13. package/es/SessionManager/user-info.js +139 -0
  14. package/es/SessionManager/user-popper.js +13 -37
  15. package/es/SessionManager/utils.js +2 -0
  16. package/es/Util/index.js +7 -0
  17. package/lib/Dialog/confirm.js +9 -7
  18. package/lib/Img/index.js +7 -7
  19. package/lib/Locale/selector.js +16 -17
  20. package/lib/SessionManager/account-item.js +140 -0
  21. package/lib/SessionManager/add-account-item.js +126 -0
  22. package/lib/SessionManager/federated-login-detecter.js +15 -9
  23. package/lib/SessionManager/index.js +125 -237
  24. package/lib/SessionManager/manage-accounts.js +155 -0
  25. package/lib/SessionManager/manage-blocklet.js +78 -0
  26. package/lib/SessionManager/menu-accordion.js +103 -0
  27. package/lib/SessionManager/translation.js +59 -0
  28. package/lib/SessionManager/use-accounts.js +25 -0
  29. package/lib/SessionManager/user-info.js +155 -0
  30. package/lib/SessionManager/user-popper.js +8 -3
  31. package/lib/SessionManager/utils.js +16 -0
  32. package/lib/Util/index.js +11 -2
  33. package/package.json +8 -5
  34. package/src/Dialog/confirm.js +9 -6
  35. package/src/Img/index.js +5 -5
  36. package/src/Locale/{selector.js → selector.jsx} +9 -10
  37. package/src/SessionManager/account-item.jsx +111 -0
  38. package/src/SessionManager/add-account-item.jsx +115 -0
  39. package/src/SessionManager/federated-login-detecter.jsx +14 -12
  40. package/src/SessionManager/index.jsx +135 -214
  41. package/src/SessionManager/manage-accounts.jsx +143 -0
  42. package/src/SessionManager/manage-blocklet.jsx +64 -0
  43. package/src/SessionManager/menu-accordion.jsx +87 -0
  44. package/src/SessionManager/translation.js +52 -0
  45. package/src/SessionManager/use-accounts.js +18 -0
  46. package/src/SessionManager/user-info.jsx +116 -0
  47. package/src/SessionManager/user-popper.jsx +9 -37
  48. package/src/SessionManager/utils.js +3 -0
  49. package/src/Util/index.js +8 -0
  50. /package/src/Avatar/{did-motif.js → did-motif.jsx} +0 -0
  51. /package/src/Avatar/{index.js → index.jsx} +0 -0
  52. /package/src/Header/{auto-hidden.js → auto-hidden.jsx} +0 -0
  53. /package/src/Header/{header.js → header.jsx} +0 -0
  54. /package/src/Header/{responsive-header.js → responsive-header.jsx} +0 -0
  55. /package/src/Locale/{context.js → context.jsx} +0 -0
@@ -1,57 +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 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
  import DidAvatar from '../Avatar';
19
- import DidAddress from '../Address';
20
- import { getUserAvatar } from '../Util';
12
+ import { getUserAvatar, sleep } from '../Util';
21
13
  import FederatedLoginDetecter from './federated-login-detecter';
22
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';
23
22
  import { jsx as _jsx } from "react/jsx-runtime";
24
23
  import { jsxs as _jsxs } from "react/jsx-runtime";
25
24
  import { Fragment as _Fragment } from "react/jsx-runtime";
26
- const translations = {
27
- en: {
28
- switchDid: 'Switch DID',
29
- switchProfile: 'Switch Profile',
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
- switchDid: '切换账户',
41
- switchProfile: '切换用户信息',
42
- switchPassport: '切换通行证',
43
- disconnect: '退出',
44
- connect: '登录',
45
- openInWallet: '打开 DID 钱包',
46
- // NOTE: 目前只有 Auth0,展示出具体的第三方名字会更好
47
- alreadyBindOAuth: '已绑定 Auth0 账号',
48
- bind: '绑定',
49
- thirdParty: '第三方登录',
50
- connectedWith: '连接至'
51
- }
52
- };
53
- const getConnectedAccounts = user => user?.connectedAccounts || user?.extraConfigs?.connectedAccounts || [];
54
- const getSourceProvider = user => user?.sourceProvider || user?.extraConfigs?.sourceProvider || 'wallet';
55
25
  function SessionManager({
56
26
  session,
57
27
  locale,
@@ -73,30 +43,29 @@ function SessionManager({
73
43
  size,
74
44
  ...rest
75
45
  }) {
76
- 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
+ });
77
53
  const userAnchorRef = useRef(null);
78
- // eslint-disable-next-line react/prop-types
79
54
  const {
80
55
  logoutOAuth,
81
- bindOAuth,
82
- configs: oauthConfigs,
83
56
  switchOAuthPassport
84
57
  } = session.useOAuth();
85
58
  const [userOpen, setUserOpen] = useState(false);
86
59
 
87
60
  // base64 img maybe have some blank char, need encodeURIComponent to transform it
88
61
  const avatar = getUserAvatar(session.user?.avatar?.replace(/\s/g, encodeURIComponent(' ')));
89
- const currentRole = useMemo(() => session.user?.passports?.find(item => item.name === session.user.role), [session.user]);
90
- const browser = useBrowser();
91
- // eslint-disable-next-line react/prop-types
92
- const {
93
- walletDid
94
- } = session.useDid({
95
- session
96
- });
97
62
  const isRawWalletAccount = getSourceProvider(session.user) === 'wallet';
98
63
  const connectedAccounts = getConnectedAccounts(session.user);
99
- 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');
100
69
  let hasBindWallet = false;
101
70
  let hasBindAccount = false;
102
71
  if (isRawWalletAccount) {
@@ -108,18 +77,57 @@ function SessionManager({
108
77
  hasBindAccount = true;
109
78
  hasBindWallet = true;
110
79
  }
111
- const oauthConfigList = Object.entries(oauthConfigs).map(([key, value]) => {
112
- return {
113
- ...value,
114
- 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'
115
102
  };
116
- }).filter(item => item.enabled);
117
- const isFirstLoading = useMemo(() => {
118
- // eslint-disable-next-line react/prop-types
119
- return session?.initialized === false && session?.loading === true;
120
- // eslint-disable-next-line react/prop-types
121
- }, [session?.initialized, session?.loading]);
122
- const masterSiteInfo = window.blocklet?.settings?.federated?.master;
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]);
123
131
  if (!session.user) {
124
132
  return /*#__PURE__*/_jsxs(_Fragment, {
125
133
  children: [showText ? /*#__PURE__*/_jsxs(Button, {
@@ -140,7 +148,7 @@ function SessionManager({
140
148
  style: {
141
149
  lineHeight: '25px'
142
150
  },
143
- children: translation.connect
151
+ children: t('connect')
144
152
  })]
145
153
  }) : /*#__PURE__*/_jsx(IconButton, {
146
154
  ref: userAnchorRef,
@@ -181,15 +189,21 @@ function SessionManager({
181
189
  function onToggleUser() {
182
190
  setUserOpen(prevOpen => !prevOpen);
183
191
  }
192
+ function close() {
193
+ setUserOpen(false);
194
+ }
184
195
  function onCloseUser(e) {
185
196
  if (userAnchorRef.current && userAnchorRef.current.contains(e.target)) {
186
197
  return;
187
198
  }
188
- setUserOpen(false);
199
+ close();
189
200
  }
190
201
  function _onLogin() {
191
202
  if (!isFirstLoading) {
192
- session.login(onLogin);
203
+ session.login((...args) => {
204
+ _connectAccount();
205
+ onLogin(...args);
206
+ });
193
207
  }
194
208
  }
195
209
  function _onLogout() {
@@ -202,19 +216,18 @@ function SessionManager({
202
216
  }).catch(err => {
203
217
  console.error(err);
204
218
  }).finally(() => {
205
- setUserOpen(false);
219
+ close();
206
220
  });
207
221
  });
208
222
  }
209
- function _onSwitchDid() {
210
- session.switchDid((...args) => {
211
- setUserOpen(false);
212
- onSwitchDid(...args);
213
- });
214
- }
223
+ /**
224
+ * @name 切换账户
225
+ * @description 该功能仅在登录后才能使用,目前仅用于切换普通登录和统一登录的账户,所以会增加一些与统一登录相关的逻辑
226
+ */
227
+
215
228
  function _onSwitchProfile() {
216
229
  session.switchProfile((...args) => {
217
- setUserOpen(false);
230
+ close();
218
231
  onSwitchProfile(...args);
219
232
  });
220
233
  }
@@ -226,25 +239,13 @@ function SessionManager({
226
239
  if (!isRawWalletAccount && provider !== 'federated') {
227
240
  switchOAuthPassport(user);
228
241
  } else {
229
- setUserOpen(false);
242
+ close();
230
243
  session.switchPassport((...args) => {
231
- setUserOpen(false);
244
+ close();
232
245
  onSwitchPassport(...args);
233
246
  });
234
247
  }
235
248
  }
236
- function _onBindWallet() {
237
- setUserOpen(false);
238
- // FIXME: @zhanghan 暂时切换回 isRawWalletAccount 的方式来判断,在 did-connect 改版时,简化这里的关系判断
239
- if (!isRawWalletAccount) {
240
- session.bindWallet((...args) => {
241
- setUserOpen(false);
242
- onBindWallet(...args);
243
- });
244
- } else {
245
- bindOAuth();
246
- }
247
- }
248
249
  return /*#__PURE__*/_jsxs(_Fragment, {
249
250
  children: [/*#__PURE__*/_jsx(IconButton, {
250
251
  ref: userAnchorRef,
@@ -273,137 +274,34 @@ function SessionManager({
273
274
  sx: {
274
275
  p: 0
275
276
  },
276
- children: [/*#__PURE__*/_jsxs("div", {
277
- className: "session-manager-user",
278
- children: [/*#__PURE__*/_jsxs("div", {
279
- className: "session-manager-user-name",
280
- role: "button",
281
- "aria-label": "User info panel",
282
- children: [/*#__PURE__*/_jsx("span", {
283
- children: session.user.fullName
284
- }), !!showRole && (currentRole?.title || session.user?.role.toUpperCase()) && /*#__PURE__*/_jsx(Chip, {
285
- label: currentRole?.title || session.user?.role.toUpperCase(),
286
- size: "small",
287
- variant: "outlined",
288
- sx: {
289
- height: 'auto',
290
- marginRight: 0
291
- },
292
- icon: /*#__PURE__*/_jsx(SvgIcon, {
293
- component: ShieldCheck,
294
- size: "small"
295
- })
296
- })]
297
- }), /*#__PURE__*/_jsxs("div", {
298
- className: "session-manager-id-list",
299
- "aria-label": "User DID list",
300
- children: [walletDid && /*#__PURE__*/_jsx("div", {
301
- className: "session-manager-id-item",
302
- children: /*#__PURE__*/_jsx(DidAddress, {
303
- responsive: false,
304
- children: walletDid
305
- })
306
- }), federatedAccount && /*#__PURE__*/_jsx("div", {
307
- className: "session-manager-id-item",
308
- children: /*#__PURE__*/_jsx(DidAddress, {
309
- responsive: false,
310
- children: federatedAccount.did
311
- })
312
- }), session?.user?.email && /*#__PURE__*/_jsx("div", {
313
- className: "session-manager-id-item",
314
- children: /*#__PURE__*/_jsx(DidAddress, {
315
- responsive: false,
316
- children: session.user.email
317
- })
318
- })]
319
- })]
320
- }), federatedAccount && !isEmpty(masterSiteInfo) && /*#__PURE__*/_jsx(MenuItem, {
321
- className: "session-manager-menu-item",
322
- "data-cy": "sessionManager-connectWithFederated",
323
- children: /*#__PURE__*/_jsxs(Box, {
324
- overflow: "hidden",
325
- textOverflow: "ellipsis",
326
- children: [/*#__PURE__*/_jsx(SvgIcon, {
327
- component: ConnectWithoutContactIcon,
328
- className: "session-manager-menu-icon"
329
- }), translation.connectedWith, /*#__PURE__*/_jsx(Link, {
330
- ml: 1,
331
- href: masterSiteInfo.appUrl,
332
- underline: "hover",
333
- target: "_blank",
334
- title: masterSiteInfo.appName,
335
- "aria-label": "Open federated master site url",
336
- children: masterSiteInfo.appName
337
- })]
338
- })
339
- }), Array.isArray(menu) && menu.map((menuItem, index) => {
340
- const {
341
- svgIcon,
342
- ...menuProps
343
- } = menuItem;
344
- return /*#__PURE__*/_jsxs(MenuItem, {
345
- className: "session-manager-menu-item",
346
- ...menuProps,
347
- icon: undefined,
348
- label: undefined,
349
- children: [svgIcon ? svgIcon && /*#__PURE__*/_jsx(SvgIcon, {
350
- component: svgIcon,
351
- className: "session-manager-menu-icon"
352
- }) : menuItem.icon, menuItem.label]
353
- }, index);
354
- }), menuRender({
355
- classes: {
356
- menuItem: 'session-manager-menu-item',
357
- menuIcon: 'session-manager-menu-icon'
358
- }
359
- }), !browser.wallet && /*#__PURE__*/_jsxs(MenuItem, {
360
- component: "a",
361
- className: "session-manager-menu-item",
362
- "data-cy": "sessionManager-openInWallet",
363
- href: "https://www.abtwallet.io/",
364
- "aria-label": translation.openInWallet,
365
- target: "_blank",
366
- children: [/*#__PURE__*/_jsx(SvgIcon, {
367
- component: OpenInIcon,
368
- className: "session-manager-menu-icon"
369
- }), translation.openInWallet]
370
- }), !!switchDid && /*#__PURE__*/_jsxs(MenuItem, {
371
- className: "session-manager-menu-item",
372
- onClick: _onSwitchDid,
373
- "aria-label": translation.switchDid,
374
- "data-cy": "sessionManager-switch-trigger",
375
- children: [/*#__PURE__*/_jsx(SvgIcon, {
376
- component: SwitchDidIcon,
377
- className: "session-manager-menu-icon"
378
- }), translation.switchDid]
379
- }), !!switchProfile && hasBindWallet && session.provider !== 'federated' && /*#__PURE__*/_jsxs(MenuItem, {
380
- className: "session-manager-menu-item",
381
- onClick: _onSwitchProfile,
382
- "aria-label": translation.switchProfile,
383
- "data-cy": "sessionManager-switch-profile-trigger",
384
- children: [/*#__PURE__*/_jsx(SvgIcon, {
385
- component: SwitchProfileIcon,
386
- className: "session-manager-menu-icon"
387
- }), translation.switchProfile]
388
- }), !!switchPassport && /*#__PURE__*/_jsxs(MenuItem, {
389
- className: "session-manager-menu-item",
390
- onClick: _onSwitchPassport,
391
- "aria-label": translation.switchPassport,
392
- "data-cy": "sessionManager-switch-passport-trigger",
393
- children: [/*#__PURE__*/_jsx(SvgIcon, {
394
- component: SwitchPassportIcon,
395
- className: "session-manager-menu-icon"
396
- }), translation.switchPassport]
397
- }), oauthConfigList.length > 0 && !hasBindAccount && session.provider !== 'federated' && /*#__PURE__*/_jsxs(MenuItem, {
398
- className: "session-manager-menu-item",
399
- onClick: _onBindWallet,
400
- "aria-label": !isRawWalletAccount ? `${translation.bind}DID Wallet` : `${translation.bind}${translation.thirdParty}`,
401
- "data-cy": "sessionManager-bind-trigger",
402
- children: [/*#__PURE__*/_jsx(SvgIcon, {
403
- component: BindWalletIcon,
404
- className: "session-manager-menu-icon"
405
- }), !isRawWalletAccount ? `${translation.bind}DID Wallet` : `${translation.bind}${translation.thirdParty}`]
406
- }), /*#__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, {
407
305
  className: "session-manager-menu-item",
408
306
  onClick: _onLogout,
409
307
  disabled: disableLogout,
@@ -412,7 +310,7 @@ function SessionManager({
412
310
  children: [/*#__PURE__*/_jsx(SvgIcon, {
413
311
  component: DisconnectIcon,
414
312
  className: "session-manager-menu-icon"
415
- }), translation.disconnect]
313
+ }), t('disconnect')]
416
314
  })]
417
315
  })
418
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
+ };