@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,14 +1,7 @@
1
1
  /* eslint-disable react/jsx-no-bind */
2
2
  import { useState, useContext, useRef, useMemo } from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import Button from '@mui/material/Button';
5
- import Typography from '@mui/material/Typography';
6
- import IconButton from '@mui/material/IconButton';
7
- import ClickAwayListener from '@mui/material/ClickAwayListener';
8
- import Popper from '@mui/material/Popper';
9
- import MenuItem from '@mui/material/MenuItem';
10
- import MenuList from '@mui/material/MenuList';
11
- import Box from '@mui/material/Box';
4
+ import { Button, Typography, IconButton, Popper, MenuItem, MenuList, Box, ClickAwayListener } from '@mui/material';
12
5
  import CheckIcon from '@mui/icons-material/Check';
13
6
  import GlobeIcon from '@arcblock/icons/lib/Globe';
14
7
 
@@ -82,7 +75,7 @@ export default function LocaleSelector(props) {
82
75
  </Box>
83
76
  </ButtonComponent>
84
77
 
85
- <Popper open={open} anchorEl={anchorEl.current} {...popperProps} disablePortal>
78
+ <StyledPopper open={open} anchorEl={anchorEl.current} {...popperProps} disablePortal>
86
79
  <div className="locales">
87
80
  <ClickAwayListener onClickAway={onClose}>
88
81
  <MenuList>
@@ -98,7 +91,7 @@ export default function LocaleSelector(props) {
98
91
  </MenuList>
99
92
  </ClickAwayListener>
100
93
  </div>
101
- </Popper>
94
+ </StyledPopper>
102
95
  </Div>
103
96
  );
104
97
  }
@@ -166,3 +159,9 @@ const Div = styled('div', {
166
159
  }
167
160
  }
168
161
  `;
162
+
163
+ const StyledPopper = styled(Popper)`
164
+ z-index: ${({ theme }) => {
165
+ return theme.zIndex.tooltip + 10;
166
+ }};
167
+ `;
@@ -0,0 +1,111 @@
1
+ import { Box, IconButton, Link, MenuItem, Typography } from '@mui/material';
2
+ import PropTypes from 'prop-types';
3
+ import { Icon } from '@iconify/react';
4
+ import CheckIcon from '@iconify-icons/mdi/check';
5
+ import TrashCanOutlineIcon from '@iconify-icons/mdi/trash-can-outline';
6
+ import { useMemoizedFn } from 'ahooks';
7
+
8
+ import Avatar from '../Avatar';
9
+ import DID from '../DID';
10
+ import { translate } from '../Locale/util';
11
+ import { translations } from './translation';
12
+
13
+ export default function AccountItem({ account, active, onDelete, onChoose, locale }) {
14
+ const t = useMemoizedFn((key, data = {}) => {
15
+ return translate(translations, key, locale, 'en', data);
16
+ });
17
+
18
+ const _onChoose = useMemoizedFn(() => onChoose(account, { active }));
19
+
20
+ const _onDelete = useMemoizedFn((e) => {
21
+ e.preventDefault();
22
+ e.stopPropagation();
23
+ onDelete(account, { active });
24
+ });
25
+
26
+ if (!account?.did || !account?.appName) {
27
+ return null;
28
+ }
29
+
30
+ return (
31
+ <MenuItem
32
+ onClick={_onChoose}
33
+ sx={{
34
+ display: 'flex',
35
+ alignItems: 'center',
36
+ overflow: 'hidden',
37
+ gap: '8px',
38
+ position: 'relative',
39
+ '.account-item-actions': {
40
+ position: 'absolute',
41
+ right: 0,
42
+ top: 0,
43
+ bottom: 0,
44
+ marginRight: '12px',
45
+ display: 'flex',
46
+ alignItems: 'center',
47
+ },
48
+ '.account-item-action': {
49
+ alignItems: 'center',
50
+ display: 'none',
51
+ },
52
+ '&:hover .account-item-action': {
53
+ display: 'flex',
54
+ },
55
+ }}
56
+ className="session-manager-menu-item">
57
+ <Avatar did={account.did} />
58
+ <Box
59
+ sx={{
60
+ flex: 1,
61
+ overflow: 'hidden',
62
+ fontSize: 0,
63
+ '.did-address-avatar': {
64
+ display: 'none !important',
65
+ },
66
+ }}>
67
+ <DID did={account.did} copyable={false} size={14} responsive={false} compact sx={{ lineHeight: 1 }} />
68
+ <Typography variant="caption">
69
+ {t('from')}{' '}
70
+ {account.provider === 'federated' ? (
71
+ <Link href={account.appUrl} target="_blank" underline="none">
72
+ {account.appName}
73
+ </Link>
74
+ ) : (
75
+ account.appName
76
+ )}
77
+ </Typography>
78
+ </Box>
79
+ <Box className="account-item-actions">
80
+ {active ? (
81
+ <Box className="account-item-action" style={{ display: 'flex' }} key="CheckIcon">
82
+ <IconButton color="success">
83
+ <Icon icon={CheckIcon} color="success" />
84
+ </IconButton>
85
+ </Box>
86
+ ) : (
87
+ <Box className="account-item-action" key="TrashCanOutlineIcon">
88
+ <IconButton color="error" onClick={_onDelete}>
89
+ <Icon icon={TrashCanOutlineIcon} color="error" />
90
+ </IconButton>
91
+ </Box>
92
+ )}
93
+ </Box>
94
+ </MenuItem>
95
+ );
96
+ }
97
+
98
+ AccountItem.propTypes = {
99
+ account: PropTypes.object,
100
+ active: PropTypes.bool,
101
+ locale: PropTypes.string,
102
+ onChoose: PropTypes.func,
103
+ onDelete: PropTypes.func,
104
+ };
105
+ AccountItem.defaultProps = {
106
+ account: null,
107
+ active: false,
108
+ locale: 'en',
109
+ onChoose: () => {},
110
+ onDelete: () => {},
111
+ };
@@ -0,0 +1,115 @@
1
+ import { Icon } from '@iconify/react';
2
+ import PropTypes from 'prop-types';
3
+ import { Menu, MenuItem, Typography } from '@mui/material';
4
+ import AddIcon from '@iconify-icons/ion/ios-add-circle-outline';
5
+ import isEmpty from 'lodash/isEmpty';
6
+ import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
7
+ import { useRef } from 'react';
8
+ import { translate } from '../Locale/util';
9
+ import { translations } from './translation';
10
+
11
+ export default function AddAccountItem({ onAdd, locale }) {
12
+ const addRef = useRef(null);
13
+ const state = useReactive({
14
+ open: false,
15
+ });
16
+
17
+ const t = useMemoizedFn((key, data = {}) => {
18
+ return translate(translations, key, locale, 'en', data);
19
+ });
20
+ const apps = useCreation(() => {
21
+ const appList = [];
22
+ if (typeof window === 'undefined') {
23
+ return appList;
24
+ }
25
+ const blocklet = window?.blocklet;
26
+ if (!blocklet) {
27
+ return appList;
28
+ }
29
+ const currentApp = {
30
+ appId: blocklet.appId,
31
+ appName: blocklet.appName,
32
+ appDescription: blocklet.appDescription,
33
+ appLogo: blocklet.appLogo,
34
+ appPid: blocklet.appPid,
35
+ appUrl: blocklet.appUrl,
36
+ version: blocklet.version,
37
+ provider: 'wallet',
38
+ };
39
+ appList.push(currentApp);
40
+ const isFederatedMember = !isEmpty(blocklet.settings?.federated?.master);
41
+ if (isFederatedMember) {
42
+ const federatedMaster = blocklet.settings.federated.master;
43
+ const masterApp = {
44
+ appId: federatedMaster.appId,
45
+ appName: federatedMaster.appName,
46
+ appDescription: federatedMaster.appDescription,
47
+ appLogo: federatedMaster.appLogo,
48
+ appPid: federatedMaster.appPid,
49
+ appUrl: federatedMaster.appUrl,
50
+ version: federatedMaster.version,
51
+ provider: 'federated',
52
+ };
53
+ return [masterApp, currentApp];
54
+ }
55
+ return appList;
56
+ }, [window.blocklet]);
57
+
58
+ const _onAdd = useMemoizedFn(() => {
59
+ if (apps.length <= 1) {
60
+ onAdd(apps[0]);
61
+ } else {
62
+ state.open = true;
63
+ }
64
+ });
65
+ const onClose = useMemoizedFn(() => {
66
+ state.open = false;
67
+ });
68
+
69
+ return (
70
+ <>
71
+ <MenuItem
72
+ ref={addRef}
73
+ onClick={_onAdd}
74
+ className="session-manager-menu-item"
75
+ sx={{ display: 'flex', gap: '8px' }}
76
+ data-cy="sessionManager-switch-trigger">
77
+ <Icon icon={AddIcon} width={24} height={24} />
78
+ <Typography>{t('addAnotherAccount')}</Typography>
79
+ </MenuItem>
80
+ {addRef.current ? (
81
+ <Menu
82
+ anchorEl={addRef.current}
83
+ open={state.open}
84
+ onClose={onClose}
85
+ elevation={0}
86
+ PaperProps={{
87
+ variant: 'outlined',
88
+ }}
89
+ anchorOrigin={{
90
+ vertical: 'top',
91
+ horizontal: 'left',
92
+ }}
93
+ transformOrigin={{
94
+ vertical: 'top',
95
+ horizontal: 'left',
96
+ }}>
97
+ {apps.map((app) => (
98
+ <MenuItem key={app.appId} onClick={() => onAdd(app)}>
99
+ Connect with {app.appName} account
100
+ </MenuItem>
101
+ ))}
102
+ </Menu>
103
+ ) : null}
104
+ </>
105
+ );
106
+ }
107
+
108
+ AddAccountItem.propTypes = {
109
+ onAdd: PropTypes.func,
110
+ locale: PropTypes.string,
111
+ };
112
+ AddAccountItem.defaultProps = {
113
+ onAdd: () => {},
114
+ locale: 'en',
115
+ };
@@ -3,8 +3,8 @@ import { useCallback, useState } from 'react';
3
3
  import Box from '@mui/material/Box';
4
4
  import Chip from '@mui/material/Chip';
5
5
  import Divider from '@mui/material/Divider';
6
- import SvgIcon from '@mui/material/SvgIcon';
7
- import ShieldCheck from 'mdi-material-ui/ShieldCheck';
6
+ import ShieldCheckIcon from '@iconify-icons/mdi/shield-check';
7
+ import { Icon } from '@iconify/react';
8
8
 
9
9
  import UserPopper from './user-popper';
10
10
  import DidAvatar from '../Avatar';
@@ -18,7 +18,7 @@ const translations = {
18
18
  useToConnect({ master, member }) {
19
19
  return (
20
20
  <>
21
- Use {master} account to connect {member}
21
+ Connect {member} with {master} account
22
22
  </>
23
23
  );
24
24
  },
@@ -63,6 +63,15 @@ export default function FederatedLoginDetecter({ session, anchorEl, dark, locale
63
63
  );
64
64
  }, [session, userInfo, _locale]);
65
65
 
66
+ let appLogoUrl;
67
+ if (siteInfo) {
68
+ appLogoUrl = new URL(siteInfo.appLogo, siteInfo.appUrl);
69
+ appLogoUrl.searchParams.set('imageFilter', 'resize');
70
+ // HACK: 保持跟其他地方使用的尺寸一致,可以复用同一资源的缓存,减少网络请求
71
+ appLogoUrl.searchParams.set('w', '80');
72
+ appLogoUrl.searchParams.set('h', '80');
73
+ }
74
+
66
75
  return (
67
76
  siteInfo && (
68
77
  <UserPopper
@@ -74,14 +83,7 @@ export default function FederatedLoginDetecter({ session, anchorEl, dark, locale
74
83
  <Box p={2}>
75
84
  {siteInfo && (
76
85
  <Box display="flex" alignItems="center">
77
- <Box
78
- component="img"
79
- mr={2}
80
- src={`${siteInfo.appUrl}${siteInfo.appLogo}`}
81
- alt={siteInfo.appName}
82
- width="30px"
83
- height="30px"
84
- />
86
+ <Box component="img" mr={2} src={appLogoUrl.href} alt={siteInfo.appName} width="30px" height="30px" />
85
87
  <Box sx={{ maxWidth: '260px' }}>
86
88
  {translations[locale].useToConnect({
87
89
  master: (
@@ -117,7 +119,7 @@ export default function FederatedLoginDetecter({ session, anchorEl, dark, locale
117
119
  size="small"
118
120
  variant="outlined"
119
121
  sx={{ height: 'auto', marginRight: 0, fontSize: 12 }}
120
- icon={<SvgIcon component={ShieldCheck} style={{ fontSize: '14px' }} />}
122
+ icon={<Icon icon={ShieldCheckIcon} fontSize={14} />}
121
123
  />
122
124
  )}
123
125
  </Box>