@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,8 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
- import { useContext, forwardRef, useRef, useImperativeHandle } from 'react';
2
+ import { forwardRef, useRef, useImperativeHandle } from 'react';
3
3
  import { useMemoizedFn, useReactive } from 'ahooks';
4
4
  import noop from 'lodash/noop';
5
- import { LocaleContext } from '../Locale/context';
6
5
  import Button from '../Button';
7
6
  import Dialog from './dialog';
8
7
 
@@ -93,16 +92,15 @@ Confirm.defaultProps = {
93
92
  PaperProps: {}
94
93
  };
95
94
  const ConfirmHolder = /*#__PURE__*/forwardRef((props, ref) => {
96
- const {
97
- t
98
- } = useContext(LocaleContext);
99
95
  const state = useReactive({
100
96
  show: false,
101
97
  title: '',
102
98
  content: '',
103
99
  onConfirm: noop,
104
100
  onCancel: noop,
105
- loading: false
101
+ loading: false,
102
+ confirmButtonText: 'Confirm',
103
+ cancelButtonText: 'Cancel'
106
104
  });
107
105
  const open = useMemoizedFn((params = {}) => {
108
106
  state.show = true;
@@ -110,6 +108,8 @@ const ConfirmHolder = /*#__PURE__*/forwardRef((props, ref) => {
110
108
  state.content = params.content;
111
109
  state.onConfirm = params.onConfirm || noop;
112
110
  state.onCancel = params.onCancel || noop;
111
+ if (params.confirmButtonText) state.confirmButtonText = params.confirmButtonText;
112
+ if (params.cancelButtonText) state.cancelButtonText = params.cancelButtonText;
113
113
  state.loading = false;
114
114
  });
115
115
  const reset = useMemoizedFn(() => {
@@ -117,6 +117,8 @@ const ConfirmHolder = /*#__PURE__*/forwardRef((props, ref) => {
117
117
  state.content = '';
118
118
  state.onConfirm = noop;
119
119
  state.onCancel = noop;
120
+ state.confirmButtonText = 'Confirm';
121
+ state.cancelButtonText = 'Cancel';
120
122
  });
121
123
  const close = useMemoizedFn(() => {
122
124
  state.show = false;
@@ -148,7 +150,7 @@ const ConfirmHolder = /*#__PURE__*/forwardRef((props, ref) => {
148
150
  onConfirm: onConfirm,
149
151
  onCancel: onCancel,
150
152
  confirmButton: {
151
- text: t('common.confirm'),
153
+ text: state.confirmButtonText,
152
154
  props: {
153
155
  variant: 'contained',
154
156
  color: 'primary',
@@ -156,7 +158,7 @@ const ConfirmHolder = /*#__PURE__*/forwardRef((props, ref) => {
156
158
  }
157
159
  },
158
160
  cancelButton: {
159
- text: t('common.cancel'),
161
+ text: state.cancelButtonText,
160
162
  props: {
161
163
  variant: 'outlined',
162
164
  color: 'primary'
package/es/Img/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { useEffect, useMemo, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import SvgIcon from '@mui/material/SvgIcon';
4
3
  import { useInView } from 'react-intersection-observer';
5
- import Alert from 'mdi-material-ui/Alert';
6
- import ImageIcon from 'mdi-material-ui/Image';
4
+ import AlertIcon from '@iconify-icons/mdi/alert';
5
+ import ImageIcon from '@iconify-icons/mdi/image';
6
+ import { Icon } from '@iconify/react';
7
7
  import { styled } from '../Theme';
8
8
 
9
9
  /**
@@ -161,15 +161,15 @@ function Img({
161
161
  children: [!fallback && imgState === 'error' && /*#__PURE__*/_jsx("div", {
162
162
  className: "image--state",
163
163
  title: "loading image",
164
- children: /*#__PURE__*/_jsx(SvgIcon, {
165
- component: Alert,
164
+ children: /*#__PURE__*/_jsx(Icon, {
165
+ icon: AlertIcon,
166
166
  className: "image--icon"
167
167
  })
168
168
  }), !placeholder && imgState === 'loading' && /*#__PURE__*/_jsx("div", {
169
169
  className: "image--state",
170
170
  title: "Image load error",
171
- children: /*#__PURE__*/_jsx(SvgIcon, {
172
- component: ImageIcon,
171
+ children: /*#__PURE__*/_jsx(Icon, {
172
+ icon: ImageIcon,
173
173
  className: "image--icon"
174
174
  })
175
175
  }), imgState === 'loaded' && /*#__PURE__*/_jsx("img", {
@@ -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
  import { getColor, getBackground } from '../Util';
@@ -92,7 +85,7 @@ export default function LocaleSelector(props) {
92
85
  children: languages.find(x => x.code === locale).name
93
86
  }) : '']
94
87
  })
95
- }), /*#__PURE__*/_jsx(Popper, {
88
+ }), /*#__PURE__*/_jsx(StyledPopper, {
96
89
  open: open,
97
90
  anchorEl: anchorEl.current,
98
91
  ...popperProps,
@@ -179,4 +172,11 @@ const Div = styled('div', {
179
172
  visibility: visible;
180
173
  }
181
174
  }
175
+ `;
176
+ const StyledPopper = styled(Popper)`
177
+ z-index: ${({
178
+ theme
179
+ }) => {
180
+ return theme.zIndex.tooltip + 10;
181
+ }};
182
182
  `;
@@ -0,0 +1,132 @@
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
+ import Avatar from '../Avatar';
8
+ import DID from '../DID';
9
+ import { translate } from '../Locale/util';
10
+ import { translations } from './translation';
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ import { jsxs as _jsxs } from "react/jsx-runtime";
13
+ export default function AccountItem({
14
+ account,
15
+ active,
16
+ onDelete,
17
+ onChoose,
18
+ locale
19
+ }) {
20
+ const t = useMemoizedFn((key, data = {}) => {
21
+ return translate(translations, key, locale, 'en', data);
22
+ });
23
+ const _onChoose = useMemoizedFn(() => onChoose(account, {
24
+ active
25
+ }));
26
+ const _onDelete = useMemoizedFn(e => {
27
+ e.preventDefault();
28
+ e.stopPropagation();
29
+ onDelete(account, {
30
+ active
31
+ });
32
+ });
33
+ if (!account?.did || !account?.appName) {
34
+ return null;
35
+ }
36
+ return /*#__PURE__*/_jsxs(MenuItem, {
37
+ onClick: _onChoose,
38
+ sx: {
39
+ display: 'flex',
40
+ alignItems: 'center',
41
+ overflow: 'hidden',
42
+ gap: '8px',
43
+ position: 'relative',
44
+ '.account-item-actions': {
45
+ position: 'absolute',
46
+ right: 0,
47
+ top: 0,
48
+ bottom: 0,
49
+ marginRight: '12px',
50
+ display: 'flex',
51
+ alignItems: 'center'
52
+ },
53
+ '.account-item-action': {
54
+ alignItems: 'center',
55
+ display: 'none'
56
+ },
57
+ '&:hover .account-item-action': {
58
+ display: 'flex'
59
+ }
60
+ },
61
+ className: "session-manager-menu-item",
62
+ children: [/*#__PURE__*/_jsx(Avatar, {
63
+ did: account.did
64
+ }), /*#__PURE__*/_jsxs(Box, {
65
+ sx: {
66
+ flex: 1,
67
+ overflow: 'hidden',
68
+ fontSize: 0,
69
+ '.did-address-avatar': {
70
+ display: 'none !important'
71
+ }
72
+ },
73
+ children: [/*#__PURE__*/_jsx(DID, {
74
+ did: account.did,
75
+ copyable: false,
76
+ size: 14,
77
+ responsive: false,
78
+ compact: true,
79
+ sx: {
80
+ lineHeight: 1
81
+ }
82
+ }), /*#__PURE__*/_jsxs(Typography, {
83
+ variant: "caption",
84
+ children: [t('from'), ' ', account.provider === 'federated' ? /*#__PURE__*/_jsx(Link, {
85
+ href: account.appUrl,
86
+ target: "_blank",
87
+ underline: "none",
88
+ children: account.appName
89
+ }) : account.appName]
90
+ })]
91
+ }), /*#__PURE__*/_jsx(Box, {
92
+ className: "account-item-actions",
93
+ children: active ? /*#__PURE__*/_jsx(Box, {
94
+ className: "account-item-action",
95
+ style: {
96
+ display: 'flex'
97
+ },
98
+ children: /*#__PURE__*/_jsx(IconButton, {
99
+ color: "success",
100
+ children: /*#__PURE__*/_jsx(Icon, {
101
+ icon: CheckIcon,
102
+ color: "success"
103
+ })
104
+ })
105
+ }, "CheckIcon") : /*#__PURE__*/_jsx(Box, {
106
+ className: "account-item-action",
107
+ children: /*#__PURE__*/_jsx(IconButton, {
108
+ color: "error",
109
+ onClick: _onDelete,
110
+ children: /*#__PURE__*/_jsx(Icon, {
111
+ icon: TrashCanOutlineIcon,
112
+ color: "error"
113
+ })
114
+ })
115
+ }, "TrashCanOutlineIcon")
116
+ })]
117
+ });
118
+ }
119
+ AccountItem.propTypes = {
120
+ account: PropTypes.object,
121
+ active: PropTypes.bool,
122
+ locale: PropTypes.string,
123
+ onChoose: PropTypes.func,
124
+ onDelete: PropTypes.func
125
+ };
126
+ AccountItem.defaultProps = {
127
+ account: null,
128
+ active: false,
129
+ locale: 'en',
130
+ onChoose: () => {},
131
+ onDelete: () => {}
132
+ };
@@ -0,0 +1,118 @@
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
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ import { jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { Fragment as _Fragment } from "react/jsx-runtime";
13
+ export default function AddAccountItem({
14
+ onAdd,
15
+ locale
16
+ }) {
17
+ const addRef = useRef(null);
18
+ const state = useReactive({
19
+ open: false
20
+ });
21
+ const t = useMemoizedFn((key, data = {}) => {
22
+ return translate(translations, key, locale, 'en', data);
23
+ });
24
+ const apps = useCreation(() => {
25
+ const appList = [];
26
+ if (typeof window === 'undefined') {
27
+ return appList;
28
+ }
29
+ const blocklet = window?.blocklet;
30
+ if (!blocklet) {
31
+ return appList;
32
+ }
33
+ const currentApp = {
34
+ appId: blocklet.appId,
35
+ appName: blocklet.appName,
36
+ appDescription: blocklet.appDescription,
37
+ appLogo: blocklet.appLogo,
38
+ appPid: blocklet.appPid,
39
+ appUrl: blocklet.appUrl,
40
+ version: blocklet.version,
41
+ provider: 'wallet'
42
+ };
43
+ appList.push(currentApp);
44
+ const isFederatedMember = !isEmpty(blocklet.settings?.federated?.master);
45
+ if (isFederatedMember) {
46
+ const federatedMaster = blocklet.settings.federated.master;
47
+ const masterApp = {
48
+ appId: federatedMaster.appId,
49
+ appName: federatedMaster.appName,
50
+ appDescription: federatedMaster.appDescription,
51
+ appLogo: federatedMaster.appLogo,
52
+ appPid: federatedMaster.appPid,
53
+ appUrl: federatedMaster.appUrl,
54
+ version: federatedMaster.version,
55
+ provider: 'federated'
56
+ };
57
+ return [masterApp, currentApp];
58
+ }
59
+ return appList;
60
+ }, [window.blocklet]);
61
+ const _onAdd = useMemoizedFn(() => {
62
+ if (apps.length <= 1) {
63
+ onAdd(apps[0]);
64
+ } else {
65
+ state.open = true;
66
+ }
67
+ });
68
+ const onClose = useMemoizedFn(() => {
69
+ state.open = false;
70
+ });
71
+ return /*#__PURE__*/_jsxs(_Fragment, {
72
+ children: [/*#__PURE__*/_jsxs(MenuItem, {
73
+ ref: addRef,
74
+ onClick: _onAdd,
75
+ className: "session-manager-menu-item",
76
+ sx: {
77
+ display: 'flex',
78
+ gap: '8px'
79
+ },
80
+ "data-cy": "sessionManager-switch-trigger",
81
+ children: [/*#__PURE__*/_jsx(Icon, {
82
+ icon: AddIcon,
83
+ width: 24,
84
+ height: 24
85
+ }), /*#__PURE__*/_jsx(Typography, {
86
+ children: t('addAnotherAccount')
87
+ })]
88
+ }), addRef.current ? /*#__PURE__*/_jsx(Menu, {
89
+ anchorEl: addRef.current,
90
+ open: state.open,
91
+ onClose: onClose,
92
+ elevation: 0,
93
+ PaperProps: {
94
+ variant: 'outlined'
95
+ },
96
+ anchorOrigin: {
97
+ vertical: 'top',
98
+ horizontal: 'left'
99
+ },
100
+ transformOrigin: {
101
+ vertical: 'top',
102
+ horizontal: 'left'
103
+ },
104
+ children: apps.map(app => /*#__PURE__*/_jsxs(MenuItem, {
105
+ onClick: () => onAdd(app),
106
+ children: ["Connect with ", app.appName, " account"]
107
+ }, app.appId))
108
+ }) : null]
109
+ });
110
+ }
111
+ AddAccountItem.propTypes = {
112
+ onAdd: PropTypes.func,
113
+ locale: PropTypes.string
114
+ };
115
+ AddAccountItem.defaultProps = {
116
+ onAdd: () => {},
117
+ locale: 'en'
118
+ };
@@ -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
  import UserPopper from './user-popper';
9
9
  import DidAvatar from '../Avatar';
10
10
  import DidAddress from '../Address';
@@ -21,7 +21,7 @@ const translations = {
21
21
  member
22
22
  }) {
23
23
  return /*#__PURE__*/_jsxs(_Fragment, {
24
- children: ["Use ", master, " account to connect ", member]
24
+ children: ["Connect ", member, " with ", master, " account"]
25
25
  });
26
26
  },
27
27
  connect: 'Connect Account',
@@ -63,6 +63,14 @@ export default function FederatedLoginDetecter({
63
63
  mode: userInfo ? 'auto' : 'manual'
64
64
  });
65
65
  }, [session, userInfo, _locale]);
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
+ }
66
74
  return siteInfo && /*#__PURE__*/_jsx(UserPopper, {
67
75
  open: federatedLoginOpen,
68
76
  anchorEl: anchorEl,
@@ -77,7 +85,7 @@ export default function FederatedLoginDetecter({
77
85
  children: [/*#__PURE__*/_jsx(Box, {
78
86
  component: "img",
79
87
  mr: 2,
80
- src: `${siteInfo.appUrl}${siteInfo.appLogo}`,
88
+ src: appLogoUrl.href,
81
89
  alt: siteInfo.appName,
82
90
  width: "30px",
83
91
  height: "30px"
@@ -132,11 +140,9 @@ export default function FederatedLoginDetecter({
132
140
  marginRight: 0,
133
141
  fontSize: 12
134
142
  },
135
- icon: /*#__PURE__*/_jsx(SvgIcon, {
136
- component: ShieldCheck,
137
- style: {
138
- fontSize: '14px'
139
- }
143
+ icon: /*#__PURE__*/_jsx(Icon, {
144
+ icon: ShieldCheckIcon,
145
+ fontSize: 14
140
146
  })
141
147
  })]
142
148
  }), /*#__PURE__*/_jsx(DidAddress, {