@arcblock/ux 2.7.16 → 2.7.18

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 (43) hide show
  1. package/es/SessionManager/account-item.js +5 -4
  2. package/es/SessionManager/add-account-item.js +13 -31
  3. package/es/SessionManager/federated-login-detecter.js +32 -26
  4. package/es/SessionManager/index.js +44 -57
  5. package/es/SessionManager/manage-accounts.js +30 -17
  6. package/es/SessionManager/manage-blocklet.js +12 -4
  7. package/es/SessionManager/menu-accordion.js +14 -5
  8. package/es/SessionManager/translation.js +10 -10
  9. package/es/SessionManager/use-config.js +34 -0
  10. package/es/SessionManager/user-info.js +51 -43
  11. package/es/SessionManager/user-popper.js +1 -18
  12. package/es/Typography/index.js +89 -0
  13. package/es/Util/federated.js +65 -0
  14. package/lib/SessionManager/account-item.js +5 -4
  15. package/lib/SessionManager/add-account-item.js +14 -32
  16. package/lib/SessionManager/federated-login-detecter.js +33 -26
  17. package/lib/SessionManager/index.js +45 -58
  18. package/lib/SessionManager/manage-accounts.js +29 -16
  19. package/lib/SessionManager/manage-blocklet.js +12 -4
  20. package/lib/SessionManager/menu-accordion.js +14 -5
  21. package/lib/SessionManager/translation.js +10 -10
  22. package/lib/SessionManager/use-config.js +41 -0
  23. package/lib/SessionManager/user-info.js +50 -42
  24. package/lib/SessionManager/user-popper.js +1 -6
  25. package/lib/Typography/index.js +100 -0
  26. package/lib/Util/federated.js +85 -0
  27. package/package.json +11 -7
  28. package/src/SessionManager/account-item.jsx +6 -8
  29. package/src/SessionManager/add-account-item.jsx +12 -30
  30. package/src/SessionManager/federated-login-detecter.jsx +39 -26
  31. package/src/SessionManager/index.jsx +48 -68
  32. package/src/SessionManager/manage-accounts.jsx +27 -13
  33. package/src/SessionManager/manage-blocklet.jsx +8 -2
  34. package/src/SessionManager/menu-accordion.jsx +10 -3
  35. package/src/SessionManager/translation.js +10 -10
  36. package/src/SessionManager/use-config.js +33 -0
  37. package/src/SessionManager/user-info.jsx +34 -34
  38. package/src/SessionManager/user-popper.jsx +1 -16
  39. package/src/Typography/index.jsx +79 -0
  40. package/src/Util/federated.js +73 -0
  41. package/es/SessionManager/use-accounts.js +0 -19
  42. package/lib/SessionManager/use-accounts.js +0 -25
  43. package/src/SessionManager/use-accounts.js +0 -18
@@ -2,11 +2,10 @@
2
2
  /* eslint-disable react/jsx-no-bind */
3
3
  import { useEffect, useMemo, useRef, useState } from 'react';
4
4
  import PropTypes from 'prop-types';
5
- import { Box, IconButton, MenuList, MenuItem, SvgIcon, Button, CircularProgress, Divider } from '@mui/material';
5
+ import { Box, IconButton, MenuList, Button, CircularProgress, Divider } from '@mui/material';
6
6
  import AccountIcon from '@arcblock/icons/lib/Account';
7
- import DisconnectIcon from '@arcblock/icons/lib/Disconnect';
8
7
  import noop from 'lodash/noop';
9
- import isEmpty from 'lodash/isEmpty';
8
+ import cloneDeep from 'lodash/cloneDeep';
10
9
  import { useLatest, useMemoizedFn } from 'ahooks';
11
10
 
12
11
  import DidAvatar from '../Avatar';
@@ -19,7 +18,8 @@ import ManageAccounts from './manage-accounts';
19
18
  import ManageBlocklet from './manage-blocklet';
20
19
  import { translations } from './translation';
21
20
  import { getConnectedAccounts, getSourceProvider } from './utils';
22
- import useAccounts from './use-accounts';
21
+ import useConfig from './use-config';
22
+ import { getCurrentApp, getFederatedApp } from '../Util/federated';
23
23
 
24
24
  function SessionManager({
25
25
  session,
@@ -40,10 +40,11 @@ function SessionManager({
40
40
  menuRender,
41
41
  dark,
42
42
  size,
43
+ showManageBlocklet,
43
44
  ...rest
44
45
  }) {
45
46
  const latestSession = useLatest(session);
46
- const { connectAccount } = useAccounts();
47
+ const { connectAccount, config, setConfig } = useConfig();
47
48
  const t = useMemoizedFn((key, data = {}) => {
48
49
  return translate(translations, key, locale, 'en', data);
49
50
  });
@@ -61,7 +62,6 @@ function SessionManager({
61
62
  return session?.initialized === false && session?.loading === true;
62
63
  }, [session?.initialized, session?.loading]);
63
64
 
64
- // const federatedAccount = connectedAccounts.find((item) => item.provider === 'federated');
65
65
  let hasBindWallet = false;
66
66
  let hasBindAccount = false;
67
67
  if (isRawWalletAccount) {
@@ -84,39 +84,18 @@ function SessionManager({
84
84
  return;
85
85
  }
86
86
  const blocklet = window?.blocklet;
87
- if (!blocklet) {
88
- return;
87
+ const currentApp = getCurrentApp(blocklet);
88
+ const masterApp = getFederatedApp(blocklet);
89
+ const targetApp = latestSession.current.user.sourceAppPid ? masterApp : currentApp;
90
+ if (targetApp) {
91
+ const loginAccount = {
92
+ did: latestSession.current.user.did,
93
+ avatar: latestSession.current.user.avatar,
94
+ provider: latestSession.current.provider,
95
+ ...targetApp,
96
+ };
97
+ connectAccount(loginAccount);
89
98
  }
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
99
  });
121
100
 
122
101
  // HACK: 用于处理 统一登录 的自动登录情况,添加一个已连接的账号
@@ -219,7 +198,7 @@ function SessionManager({
219
198
 
220
199
  function _onSwitchPassport() {
221
200
  const { user, provider } = session;
222
- if (!isRawWalletAccount && provider !== 'federated') {
201
+ if (['auth0'].includes(provider)) {
223
202
  switchOAuthPassport(user);
224
203
  } else {
225
204
  close();
@@ -250,7 +229,7 @@ function SessionManager({
250
229
  session={session}
251
230
  size={size}
252
231
  locale={locale}
253
- onEditUser={() => {
232
+ onSwitchProfile={() => {
254
233
  close();
255
234
  _onSwitchProfile();
256
235
  }}
@@ -273,35 +252,34 @@ function SessionManager({
273
252
  connectAccount={_connectAccount}
274
253
  close={close}
275
254
  hasBindAccount={hasBindAccount}
255
+ onLogout={_onLogout}
256
+ expanded={config.expandAccount}
257
+ onExpand={(value) => {
258
+ const cloneConfig = cloneDeep(config);
259
+ cloneConfig.expandAccount = value;
260
+ setConfig(cloneConfig);
261
+ }}
276
262
  />
277
263
 
278
- <Divider />
279
-
280
- <ManageBlocklet menu={menu} menuRender={menuRender} locale={locale} />
281
-
282
- <Divider />
283
-
284
- {/* NOTE: federated 登录方式不允许切换 profile */}
285
- {/* {!!switchProfile && hasBindWallet && session.provider !== 'federated' && (
286
- <MenuItem
287
- className="session-manager-menu-item"
288
- onClick={_onSwitchProfile}
289
- aria-label={translation.switchProfile}
290
- data-cy="sessionManager-switch-profile-trigger">
291
- <SvgIcon component={SwitchProfileIcon} className="session-manager-menu-icon" />
292
- {translation.switchProfile}
293
- </MenuItem>
294
- )} */}
295
-
296
- <MenuItem
297
- className="session-manager-menu-item"
298
- onClick={_onLogout}
299
- disabled={disableLogout}
300
- aria-label="Logout account"
301
- data-cy="sessionManager-logout-trigger">
302
- <SvgIcon component={DisconnectIcon} className="session-manager-menu-icon" />
303
- {t('disconnect')}
304
- </MenuItem>
264
+ {/* 为了避免控制台出现警告,采用数组的方式 */}
265
+ {/* MUI:The Menu component doesn't accept a Fragment as a child. Consider providing an array instead. */}
266
+ {showManageBlocklet
267
+ ? [
268
+ <Divider key="divider" />,
269
+ <ManageBlocklet
270
+ key="manageBlocklet"
271
+ menu={menu}
272
+ menuRender={menuRender}
273
+ locale={locale}
274
+ expanded={config.expandBlocklet}
275
+ onExpand={(value) => {
276
+ const cloneConfig = cloneDeep(config);
277
+ cloneConfig.expandBlocklet = value;
278
+ setConfig(cloneConfig);
279
+ }}
280
+ />,
281
+ ]
282
+ : null}
305
283
  </MenuList>
306
284
  </UserPopper>
307
285
  </>
@@ -311,7 +289,7 @@ function SessionManager({
311
289
  SessionManager.propTypes = {
312
290
  session: PropTypes.shape({
313
291
  federatedMaster: PropTypes.object,
314
- provider: PropTypes.oneOf(['wallet', 'federated', 'auth0', '']),
292
+ provider: PropTypes.oneOf(['wallet', 'auth0', '']),
315
293
  user: PropTypes.shape({
316
294
  did: PropTypes.string.isRequired,
317
295
  role: PropTypes.string.isRequired,
@@ -360,6 +338,7 @@ SessionManager.propTypes = {
360
338
  menuRender: PropTypes.func,
361
339
  dark: PropTypes.bool,
362
340
  size: PropTypes.number,
341
+ showManageBlocklet: PropTypes.bool,
363
342
  };
364
343
 
365
344
  SessionManager.defaultProps = {
@@ -380,6 +359,7 @@ SessionManager.defaultProps = {
380
359
  onBindWallet: noop,
381
360
  dark: false,
382
361
  size: 24,
362
+ showManageBlocklet: true,
383
363
  };
384
364
 
385
365
  export default SessionManager;
@@ -1,10 +1,11 @@
1
1
  /* eslint-disable react/prop-types */
2
2
  /* eslint-disable react/jsx-no-bind */
3
3
  import { useMemoizedFn, useUpdate } from 'ahooks';
4
- import { MenuItem } from '@mui/material';
4
+ import { MenuItem, SvgIcon } from '@mui/material';
5
5
  import { Icon } from '@iconify/react';
6
6
  import AccountIcon from '@arcblock/icons/lib/Account';
7
7
  import LinkIcon from '@iconify-icons/mdi/link';
8
+ import DisconnectIcon from '@arcblock/icons/lib/Disconnect';
8
9
 
9
10
  import AccountItem from './account-item';
10
11
  import MenuAccordion from './menu-accordion';
@@ -13,7 +14,7 @@ import { translate } from '../Locale/util';
13
14
  import { useConfirm } from '../Dialog/confirm';
14
15
  import { getSourceProvider } from './utils';
15
16
  import AddAccountItem from './add-account-item';
16
- import useAccounts from './use-accounts';
17
+ import useConfig from './use-config';
17
18
 
18
19
  export default function ManageAccounts({
19
20
  session,
@@ -23,6 +24,10 @@ export default function ManageAccounts({
23
24
  connectAccount,
24
25
  close,
25
26
  hasBindAccount,
27
+ disableLogout,
28
+ onLogout,
29
+ expanded,
30
+ onExpand,
26
31
  }) {
27
32
  const { bindOAuth, configs: oauthConfigs } = session.useOAuth();
28
33
  const t = useMemoizedFn((key, data = {}) => {
@@ -30,7 +35,7 @@ export default function ManageAccounts({
30
35
  });
31
36
 
32
37
  const { confirmApi, confirmHolder } = useConfirm();
33
- const { accounts, setAccounts } = useAccounts();
38
+ const { deleteAccount, config } = useConfig();
34
39
  const update = useUpdate();
35
40
 
36
41
  const onChoose = useMemoizedFn((account, { active }) => {
@@ -45,7 +50,7 @@ export default function ManageAccounts({
45
50
  },
46
51
  {
47
52
  provider: account.provider,
48
- providerMode: 'paramsFirst',
53
+ sourceAppPid: account.sourceAppPid,
49
54
  }
50
55
  );
51
56
  });
@@ -68,11 +73,8 @@ export default function ManageAccounts({
68
73
  confirmButtonText: t('confirm'),
69
74
  cancelButtonText: t('cancel'),
70
75
  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
+ deleteAccount(account);
77
+
76
78
  update();
77
79
  done();
78
80
  },
@@ -88,8 +90,8 @@ export default function ManageAccounts({
88
90
  onSwitchDid(...args);
89
91
  },
90
92
  {
93
+ sourceAppPid: app.sourceAppPid,
91
94
  provider: app.provider,
92
- providerMode: 'paramsFirst',
93
95
  }
94
96
  );
95
97
  });
@@ -107,14 +109,16 @@ export default function ManageAccounts({
107
109
  return (
108
110
  <>
109
111
  <MenuAccordion
112
+ expanded={expanded}
113
+ onChange={onExpand}
110
114
  locale={locale}
111
115
  title={
112
116
  <>
113
117
  <AccountIcon className="session-manager-menu-icon" style={{ width: 24, height: 24 }} />
114
- {t('manageAccounts')}
118
+ {t('accounts')}
115
119
  </>
116
120
  }>
117
- {accounts.map((item) => (
121
+ {config.accounts.map((item) => (
118
122
  <AccountItem
119
123
  key={item.did}
120
124
  account={item}
@@ -126,7 +130,7 @@ export default function ManageAccounts({
126
130
  ))}
127
131
  <AddAccountItem locale={locale} onAdd={onAdd} />
128
132
 
129
- {oauthConfigList.length > 0 && !hasBindAccount && session.provider !== 'federated' && (
133
+ {oauthConfigList.length > 0 && !hasBindAccount && (
130
134
  <MenuItem
131
135
  className="session-manager-menu-item"
132
136
  onClick={_onBindWallet}
@@ -136,6 +140,16 @@ export default function ManageAccounts({
136
140
  {!isRawWalletAccount ? `${t('bind')}DID Wallet` : `${t('bind')}${t('thirdParty')}`}
137
141
  </MenuItem>
138
142
  )}
143
+
144
+ <MenuItem
145
+ className="session-manager-menu-item"
146
+ onClick={onLogout}
147
+ disabled={disableLogout}
148
+ aria-label="Logout account"
149
+ data-cy="sessionManager-logout-trigger">
150
+ <SvgIcon component={DisconnectIcon} className="session-manager-menu-icon" />
151
+ {t('disconnect')}
152
+ </MenuItem>
139
153
  </MenuAccordion>
140
154
  {confirmHolder}
141
155
  </>
@@ -9,18 +9,20 @@ import MenuAccordion from './menu-accordion';
9
9
  import { translate } from '../Locale/util';
10
10
  import { translations } from './translation';
11
11
 
12
- export default function ManageBlocklet({ menu, menuRender, locale }) {
12
+ export default function ManageBlocklet({ menu, menuRender, locale, expanded, onExpand }) {
13
13
  const t = useMemoizedFn((key, data = {}) => {
14
14
  return translate(translations, key, locale, 'en', data);
15
15
  });
16
16
 
17
17
  return (
18
18
  <MenuAccordion
19
+ expanded={expanded}
19
20
  locale={locale}
21
+ onChange={onExpand}
20
22
  title={
21
23
  <>
22
24
  <Icon icon={AppsIcon} width={24} height={24} className="session-manager-menu-icon" />
23
- {t('manageBlocklet')}
25
+ {t('blocklet')}
24
26
  </>
25
27
  }>
26
28
  {Array.isArray(menu) &&
@@ -56,9 +58,13 @@ ManageBlocklet.propTypes = {
56
58
  menu: PropTypes.array,
57
59
  menuRender: PropTypes.func,
58
60
  locale: PropTypes.string.isRequired,
61
+ expanded: PropTypes.bool,
62
+ onExpand: PropTypes.func,
59
63
  };
60
64
 
61
65
  ManageBlocklet.defaultProps = {
62
66
  menu: [],
63
67
  menuRender: () => {},
68
+ expanded: true,
69
+ onExpand: () => {},
64
70
  };
@@ -21,7 +21,7 @@ function isEmptyNode(node) {
21
21
  return false;
22
22
  }
23
23
 
24
- export default function MenuAccordion({ title, children, locale }) {
24
+ export default function MenuAccordion({ title, children, locale, expanded, onChange }) {
25
25
  const isEmptyChildren = useCreation(() => isEmptyNode(children), [children]);
26
26
  const t = useMemoizedFn((key, data = {}) => {
27
27
  return translate(translations, key, locale, 'en', data);
@@ -29,9 +29,12 @@ export default function MenuAccordion({ title, children, locale }) {
29
29
 
30
30
  return (
31
31
  <Accordion
32
- defaultExpanded
32
+ expanded={expanded}
33
33
  disableGutters
34
34
  elevation={0}
35
+ onChange={(e, value) => {
36
+ onChange(value);
37
+ }}
35
38
  sx={{
36
39
  '&.MuiAccordion-root:before': {
37
40
  content: 'unset',
@@ -48,7 +51,7 @@ export default function MenuAccordion({ title, children, locale }) {
48
51
  paddingLeft: '30px',
49
52
  '.session-manager-menu-item': {
50
53
  fontSize: '15px',
51
- padding: '12px 20px',
54
+ padding: '12px 15px',
52
55
  whiteSpace: 'normal',
53
56
  },
54
57
  '.session-manager-menu-icon': {
@@ -81,7 +84,11 @@ MenuAccordion.propTypes = {
81
84
  title: PropTypes.any.isRequired,
82
85
  children: PropTypes.any.isRequired,
83
86
  locale: PropTypes.string,
87
+ expanded: PropTypes.bool,
88
+ onChange: PropTypes.func,
84
89
  };
85
90
  MenuAccordion.defaultProps = {
86
91
  locale: 'en',
92
+ expanded: true,
93
+ onChange: () => {},
87
94
  };
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable import/prefer-default-export */
2
2
  export const translations = {
3
3
  en: {
4
- edit: 'Edit',
4
+ switch: 'Switch',
5
5
  account: 'account',
6
6
  switchDid: 'Switch DID',
7
7
  switchTo: 'Switch to',
@@ -13,9 +13,9 @@ export const translations = {
13
13
  alreadyBindOAuth: 'Already bind Auth0',
14
14
  bind: 'Bind ',
15
15
  thirdParty: 'Third Party Login',
16
- connectedWith: 'Connected with',
17
- manageAccounts: 'Manage Accounts',
18
- manageBlocklet: 'Manage Blocklet',
16
+ addAppAccount: 'Add {appName} account',
17
+ accounts: 'Accounts',
18
+ blocklet: 'Blocklet',
19
19
  from: 'From',
20
20
  addAnotherAccount: 'Add another account',
21
21
  deleteAccountTitle: 'Remove this account ?',
@@ -25,24 +25,24 @@ export const translations = {
25
25
  noneMenu: 'Empty menu, maybe you should switch to another role',
26
26
  },
27
27
  zh: {
28
- edit: '编辑',
28
+ switch: '切换',
29
29
  account: '账号',
30
30
  switchDid: '切换账户',
31
31
  switchTo: '切换至',
32
32
  switchProfile: '切换用户信息',
33
33
  switchPassport: '切换通行证',
34
- disconnect: '退出',
34
+ disconnect: '退出登录',
35
35
  connect: '登录',
36
36
  openInWallet: '打开 DID 钱包',
37
37
  // NOTE: 目前只有 Auth0,展示出具体的第三方名字会更好
38
38
  alreadyBindOAuth: '已绑定 Auth0 账号',
39
39
  bind: '绑定',
40
40
  thirdParty: '第三方登录',
41
- connectedWith: '连接至',
42
- manageAccounts: '管理账户',
43
- manageBlocklet: '管理应用',
41
+ addAppAccount: '添加 {appName} 账户',
42
+ accounts: '账户',
43
+ blocklet: '应用',
44
44
  from: '连接至',
45
- addAnotherAccount: '添加一个账号',
45
+ addAnotherAccount: '添加账号',
46
46
  deleteAccountTitle: '是否删除账户?',
47
47
  deleteAccountContent: '账户删除后,可再次添加',
48
48
  confirm: '确认',
@@ -0,0 +1,33 @@
1
+ import { useLocalStorageState, useMemoizedFn } from 'ahooks';
2
+ import cloneDeep from 'lodash/cloneDeep';
3
+
4
+ export default function useConfig() {
5
+ const [config, setConfig] = useLocalStorageState('blocklet:sessionManager:config', {
6
+ defaultValue: {
7
+ accounts: [],
8
+ expandAccount: true,
9
+ expandBlocklet: true,
10
+ },
11
+ });
12
+
13
+ const connectAccount = useMemoizedFn((account) => {
14
+ const cloneConfig = cloneDeep(config);
15
+ const accountIndex = cloneConfig.accounts.findIndex((x) => x.did === account.did);
16
+ if (accountIndex >= 0) {
17
+ cloneConfig.accounts.splice(accountIndex, 1);
18
+ }
19
+ cloneConfig.accounts.unshift(account);
20
+ setConfig(cloneConfig);
21
+ });
22
+
23
+ const deleteAccount = useMemoizedFn((account) => {
24
+ const cloneConfig = cloneDeep(config);
25
+ const findIndex = cloneConfig.accounts.findIndex((item) => item.did === account.did);
26
+ if (findIndex >= 0) {
27
+ cloneConfig.accounts.splice(findIndex, 1);
28
+ }
29
+ setConfig(cloneConfig);
30
+ });
31
+
32
+ return { config, setConfig, connectAccount, deleteAccount };
33
+ }
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable react/jsx-no-bind */
2
2
  /* eslint-disable react/prop-types */
3
- import { Box, Chip, Typography } from '@mui/material';
3
+ import { Box, Chip } from '@mui/material';
4
4
  import ShieldCheckIcon from '@iconify-icons/mdi/shield-check';
5
5
  import ExpandMoreIcon from '@iconify-icons/mdi/expand-more';
6
6
  import { Icon } from '@iconify/react';
@@ -12,8 +12,9 @@ import DID from '../DID';
12
12
  import { getUserAvatar } from '../Util';
13
13
  import { t as translate } from '../Locale/util';
14
14
  import { translations } from './translation';
15
+ import Typography from '../Typography';
15
16
 
16
- export default function UserInfo({ session, locale, onEditUser, onSwitchPassport, switchProfile, hasBindWallet }) {
17
+ export default function UserInfo({ session, locale, onSwitchProfile, onSwitchPassport, switchProfile, hasBindWallet }) {
17
18
  const t = (key, data = {}) => {
18
19
  return translate(translations, key, locale, 'en', data);
19
20
  };
@@ -26,17 +27,17 @@ export default function UserInfo({ session, locale, onEditUser, onSwitchPassport
26
27
  const userEmail = useCreation(() => session.user?.email || 'lancelot_lewis@163.com', [session?.user]);
27
28
 
28
29
  const canEdit = useCreation(() => {
29
- if (onEditUser instanceof Function) {
30
- if (switchProfile && hasBindWallet && session.provider !== 'federated') {
30
+ if (onSwitchProfile instanceof Function) {
31
+ if (switchProfile && hasBindWallet) {
31
32
  return true;
32
33
  }
33
34
  }
34
35
  return false;
35
- }, [onEditUser, switchProfile, hasBindWallet, session.provider]);
36
+ }, [onSwitchProfile, switchProfile, hasBindWallet, session.provider]);
36
37
 
37
- const _onEditUser = useMemoizedFn(() => {
38
+ const _onSwitchProfile = useMemoizedFn(() => {
38
39
  if (canEdit) {
39
- onEditUser();
40
+ onSwitchProfile();
40
41
  }
41
42
  });
42
43
 
@@ -45,11 +46,11 @@ export default function UserInfo({ session, locale, onEditUser, onSwitchPassport
45
46
  sx={{
46
47
  display: 'flex',
47
48
  alignItems: 'center',
48
- gap: '16px',
49
- padding: '15px 20px',
49
+ gap: '12px',
50
+ padding: '15px',
50
51
  }}>
51
52
  <Box
52
- onClick={_onEditUser}
53
+ onClick={_onSwitchProfile}
53
54
  data-cy="sessionManager-switch-profile-trigger"
54
55
  sx={{
55
56
  cursor: canEdit ? 'pointer' : 'default',
@@ -60,7 +61,7 @@ export default function UserInfo({ session, locale, onEditUser, onSwitchPassport
60
61
  '&:hover': canEdit
61
62
  ? {
62
63
  '&::after': {
63
- content: `"${t('edit')}"`,
64
+ content: `"${t('switch')}"`,
64
65
  position: 'absolute',
65
66
  bottom: 0,
66
67
  background: 'rgba(0, 0, 0, 0.2)',
@@ -78,9 +79,28 @@ export default function UserInfo({ session, locale, onEditUser, onSwitchPassport
78
79
  <DidAvatar variant="circle" did={session.user.did} src={avatar} size={64} shape="circle" />
79
80
  </Box>
80
81
  <Box sx={{ flex: 1, position: 'static', overflow: 'hidden', fontSize: '14px' }}>
81
- <Typography variant="h5" fontWeight="bold" mb={1}>
82
- {session.user.fullName}
83
- </Typography>
82
+ <Box display="flex" alignItems="center" gap="4px" mb={0.5}>
83
+ <Typography variant="h5" fontWeight="bold" fontSize="auto" sx={{ flex: 1, wordBreak: 'break-all' }}>
84
+ {session.user.fullName}
85
+ </Typography>
86
+ <Chip
87
+ label={currentRole?.title || session.user?.role.toUpperCase()}
88
+ size="small"
89
+ variant="outlined"
90
+ sx={{
91
+ height: 'auto',
92
+ marginRight: 0,
93
+ fontWeight: 'bold',
94
+ fontSize: '12px',
95
+ }}
96
+ icon={<Icon icon={ShieldCheckIcon} height="0.8em" />}
97
+ deleteIcon={<Icon icon={ExpandMoreIcon} height="1em" />}
98
+ // HACK: 必须设置 onDelete 函数,deleteIcon 才能显示出来
99
+ onDelete={onSwitchPassport}
100
+ onClick={onSwitchPassport}
101
+ data-cy="sessionManager-switch-passport-trigger"
102
+ />
103
+ </Box>
84
104
  {/* eslint-disable-next-line no-nested-ternary */}
85
105
  {session.provider === 'auth0' ? (
86
106
  walletDid ? (
@@ -90,26 +110,6 @@ export default function UserInfo({ session, locale, onEditUser, onSwitchPassport
90
110
  <DID responsive={false} compact did={session.user.did} />
91
111
  )}
92
112
  {userEmail ? <DidAddress responsive={false}>{userEmail}</DidAddress> : null}
93
- <Chip
94
- label={currentRole?.title || session.user?.role.toUpperCase()}
95
- size="small"
96
- variant="outlined"
97
- sx={{
98
- height: 'auto',
99
- marginRight: 0,
100
- position: 'absolute',
101
- top: 20,
102
- right: 15,
103
- fontWeight: 'bold',
104
- fontSize: '12px',
105
- }}
106
- icon={<Icon icon={ShieldCheckIcon} height="0.8em" />}
107
- deleteIcon={<Icon icon={ExpandMoreIcon} height="1em" />}
108
- // HACK: 必须设置 onDelete 函数,deleteIcon 才能显示出来
109
- onDelete={onSwitchPassport}
110
- onClick={onSwitchPassport}
111
- data-cy="sessionManager-switch-passport-trigger"
112
- />
113
113
  </Box>
114
114
  </Box>
115
115
  );
@@ -78,23 +78,8 @@ const StyledPopper = styled(Popper)`
78
78
  .MuiList-root {
79
79
  width: 320px;
80
80
  }
81
- .session-manager-user {
82
- font-size: 12px;
83
- flex-direction: column;
84
- align-items: flex-start;
85
- padding: 24px 24px 10px;
86
- }
87
- .session-manager-user-name {
88
- font-size: 20px;
89
- color: ${({ $dark }) => ($dark ? '#aaa' : '#222')};
90
- font-weight: bold;
91
- margin-bottom: 10px;
92
- display: flex;
93
- align-items: center;
94
- justify-content: space-between;
95
- }
96
81
  .session-manager-menu-item {
97
- padding: 18px 20px;
82
+ padding: 15px;
98
83
  color: #777;
99
84
  font-size: 16px;
100
85
  &:hover {