@arcblock/ux 2.7.13 → 2.7.15
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.
- package/es/CardSelector/index.js +19 -2
- package/es/Dialog/confirm.js +98 -2
- package/es/Dialog/index.js +2 -1
- package/es/Locale/selector.js +9 -9
- package/es/SessionManager/federated-login-detecter.js +10 -2
- package/es/SessionManager/index.js +50 -24
- package/es/SessionManager/user-popper.js +3 -1
- package/lib/CardSelector/index.js +16 -1
- package/lib/Dialog/confirm.js +108 -2
- package/lib/Dialog/index.js +9 -1
- package/lib/Locale/selector.js +16 -17
- package/lib/SessionManager/federated-login-detecter.js +10 -2
- package/lib/SessionManager/index.js +50 -24
- package/package.json +4 -4
- package/src/CardSelector/index.jsx +16 -2
- package/src/Dialog/confirm.js +106 -1
- package/src/Dialog/index.js +1 -0
- package/src/Locale/{selector.js → selector.jsx} +9 -10
- package/src/SessionManager/federated-login-detecter.jsx +11 -9
- package/src/SessionManager/index.jsx +55 -26
- package/src/SessionManager/user-popper.jsx +3 -1
- /package/src/Locale/{context.js → context.jsx} +0 -0
package/es/CardSelector/index.js
CHANGED
@@ -60,6 +60,21 @@ export default function CardSelector({
|
|
60
60
|
transform: `translate(${-translateX}px, 0)`
|
61
61
|
},
|
62
62
|
children: list.map((e, i) => {
|
63
|
+
if (e instanceof Function) {
|
64
|
+
return /*#__PURE__*/_jsx("div", {
|
65
|
+
className: `card-item ${i === selectedId ? 'selected' : ''}`,
|
66
|
+
style: {
|
67
|
+
width,
|
68
|
+
height,
|
69
|
+
margin: cardSpace / 2
|
70
|
+
}
|
71
|
+
// eslint-disable-next-line react/no-array-index-key
|
72
|
+
,
|
73
|
+
|
74
|
+
onClick: () => selectedItem(i),
|
75
|
+
children: e(i)
|
76
|
+
}, i);
|
77
|
+
}
|
63
78
|
return /*#__PURE__*/_jsx("div", {
|
64
79
|
className: `card-item ${i === selectedId ? 'selected' : ''}`,
|
65
80
|
style: {
|
@@ -96,7 +111,8 @@ const Contianer = styled.div`
|
|
96
111
|
align-items: center;
|
97
112
|
flex-shrink: 0;
|
98
113
|
cursor: pointer;
|
99
|
-
img
|
114
|
+
img,
|
115
|
+
svg {
|
100
116
|
max-width: 100%;
|
101
117
|
max-height: 100%;
|
102
118
|
width: auto;
|
@@ -107,7 +123,8 @@ const Contianer = styled.div`
|
|
107
123
|
}
|
108
124
|
&.selected {
|
109
125
|
cursor: default;
|
110
|
-
img
|
126
|
+
img,
|
127
|
+
svg {
|
111
128
|
outline: #526ded solid 5px;
|
112
129
|
}
|
113
130
|
}
|
package/es/Dialog/confirm.js
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
import PropTypes from 'prop-types';
|
2
|
+
import { useContext, forwardRef, useRef, useImperativeHandle } from 'react';
|
3
|
+
import { useMemoizedFn, useReactive } from 'ahooks';
|
4
|
+
import noop from 'lodash/noop';
|
5
|
+
import { LocaleContext } from '../Locale/context';
|
2
6
|
import Button from '../Button';
|
3
7
|
import Dialog from './dialog';
|
4
8
|
|
@@ -12,7 +16,7 @@ import Dialog from './dialog';
|
|
12
16
|
@property {boolean} [showCancelButton=true]
|
13
17
|
@property {{text: string, props?: import('../Button/wrap').ButtonProps}} [confirmButton={text: 'Confirm'}]
|
14
18
|
@property {{text: string, props?: import('../Button/wrap').ButtonProps}} [cancelButton={text: 'Cancel'}]
|
15
|
-
@property {import('@mui/material').PaperProps} [PaperProps={}]
|
19
|
+
@property {import('@mui/material').PaperProps} [PaperProps={}]
|
16
20
|
*/
|
17
21
|
|
18
22
|
// 注意排在 {...rest} 之后的 props 优先级更高
|
@@ -87,4 +91,96 @@ Confirm.defaultProps = {
|
|
87
91
|
text: 'Cancel'
|
88
92
|
},
|
89
93
|
PaperProps: {}
|
90
|
-
};
|
94
|
+
};
|
95
|
+
const ConfirmHolder = /*#__PURE__*/forwardRef((props, ref) => {
|
96
|
+
const {
|
97
|
+
t
|
98
|
+
} = useContext(LocaleContext);
|
99
|
+
const state = useReactive({
|
100
|
+
show: false,
|
101
|
+
title: '',
|
102
|
+
content: '',
|
103
|
+
onConfirm: noop,
|
104
|
+
onCancel: noop,
|
105
|
+
loading: false
|
106
|
+
});
|
107
|
+
const open = useMemoizedFn((params = {}) => {
|
108
|
+
state.show = true;
|
109
|
+
state.title = params.title;
|
110
|
+
state.content = params.content;
|
111
|
+
state.onConfirm = params.onConfirm || noop;
|
112
|
+
state.onCancel = params.onCancel || noop;
|
113
|
+
state.loading = false;
|
114
|
+
});
|
115
|
+
const reset = useMemoizedFn(() => {
|
116
|
+
state.title = '';
|
117
|
+
state.content = '';
|
118
|
+
state.onConfirm = noop;
|
119
|
+
state.onCancel = noop;
|
120
|
+
});
|
121
|
+
const close = useMemoizedFn(() => {
|
122
|
+
state.show = false;
|
123
|
+
setTimeout(() => {
|
124
|
+
reset();
|
125
|
+
}, 300);
|
126
|
+
});
|
127
|
+
const onCancel = useMemoizedFn(() => {
|
128
|
+
close();
|
129
|
+
state?.onCancel();
|
130
|
+
}, []);
|
131
|
+
const onConfirm = useMemoizedFn(async () => {
|
132
|
+
state.loading = true;
|
133
|
+
try {
|
134
|
+
await state?.onConfirm(close);
|
135
|
+
} finally {
|
136
|
+
state.loading = false;
|
137
|
+
}
|
138
|
+
}, []);
|
139
|
+
useImperativeHandle(ref, () => {
|
140
|
+
return {
|
141
|
+
open,
|
142
|
+
close
|
143
|
+
};
|
144
|
+
}, [open, close]);
|
145
|
+
return /*#__PURE__*/_jsx(Confirm, {
|
146
|
+
open: state.show,
|
147
|
+
title: state.title,
|
148
|
+
onConfirm: onConfirm,
|
149
|
+
onCancel: onCancel,
|
150
|
+
confirmButton: {
|
151
|
+
text: t('common.confirm'),
|
152
|
+
props: {
|
153
|
+
variant: 'contained',
|
154
|
+
color: 'primary',
|
155
|
+
loading: state.loading
|
156
|
+
}
|
157
|
+
},
|
158
|
+
cancelButton: {
|
159
|
+
text: t('common.cancel'),
|
160
|
+
props: {
|
161
|
+
variant: 'outlined',
|
162
|
+
color: 'primary'
|
163
|
+
}
|
164
|
+
},
|
165
|
+
children: state.content
|
166
|
+
});
|
167
|
+
});
|
168
|
+
export function useConfirm() {
|
169
|
+
const confirmRef = useRef(null);
|
170
|
+
const open = useMemoizedFn((...args) => {
|
171
|
+
confirmRef.current?.open(...args);
|
172
|
+
});
|
173
|
+
const close = useMemoizedFn((...args) => {
|
174
|
+
confirmRef.current?.close(...args);
|
175
|
+
});
|
176
|
+
const confirmApi = {
|
177
|
+
open,
|
178
|
+
close
|
179
|
+
};
|
180
|
+
return {
|
181
|
+
confirmHolder: /*#__PURE__*/_jsx(ConfirmHolder, {
|
182
|
+
ref: confirmRef
|
183
|
+
}),
|
184
|
+
confirmApi
|
185
|
+
};
|
186
|
+
}
|
package/es/Dialog/index.js
CHANGED
package/es/Locale/selector.js
CHANGED
@@ -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
|
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(
|
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
|
`;
|
@@ -21,7 +21,7 @@ const translations = {
|
|
21
21
|
member
|
22
22
|
}) {
|
23
23
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
24
|
-
children: ["
|
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:
|
88
|
+
src: appLogoUrl.href,
|
81
89
|
alt: siteInfo.appName,
|
82
90
|
width: "30px",
|
83
91
|
height: "30px"
|
@@ -6,15 +6,14 @@ import { Box, IconButton, MenuList, MenuItem, SvgIcon, Button, Chip, Link, Circu
|
|
6
6
|
import SwitchProfileIcon from '@mui/icons-material/PersonOutline';
|
7
7
|
import BindWalletIcon from '@mui/icons-material/Link';
|
8
8
|
import SwitchPassportIcon from '@mui/icons-material/VpnKeyOutlined';
|
9
|
-
import ConnectWithoutContactIcon from '@mui/icons-material/ConnectWithoutContact';
|
10
9
|
import ShieldCheck from 'mdi-material-ui/ShieldCheck';
|
11
10
|
import AccountIcon from '@arcblock/icons/lib/Account';
|
12
11
|
import OpenInIcon from '@arcblock/icons/lib/OpenIn';
|
13
12
|
import DisconnectIcon from '@arcblock/icons/lib/Disconnect';
|
14
13
|
import SwitchDidIcon from '@arcblock/icons/lib/Switch';
|
15
14
|
import useBrowser from '@arcblock/react-hooks/lib/useBrowser';
|
16
|
-
import isEmpty from 'lodash/isEmpty';
|
17
15
|
import noop from 'lodash/noop';
|
16
|
+
import isEmpty from 'lodash/isEmpty';
|
18
17
|
import DidAvatar from '../Avatar';
|
19
18
|
import DidAddress from '../Address';
|
20
19
|
import { getUserAvatar } from '../Util';
|
@@ -25,7 +24,9 @@ import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
25
24
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
26
25
|
const translations = {
|
27
26
|
en: {
|
27
|
+
account: 'account',
|
28
28
|
switchDid: 'Switch DID',
|
29
|
+
switchTo: 'Switch to',
|
29
30
|
switchProfile: 'Switch Profile',
|
30
31
|
switchPassport: 'Switch Passport',
|
31
32
|
disconnect: 'Disconnect',
|
@@ -37,7 +38,9 @@ const translations = {
|
|
37
38
|
connectedWith: 'Connected with'
|
38
39
|
},
|
39
40
|
zh: {
|
41
|
+
account: '账号',
|
40
42
|
switchDid: '切换账户',
|
43
|
+
switchTo: '切换至',
|
41
44
|
switchProfile: '切换用户信息',
|
42
45
|
switchPassport: '切换通行证',
|
43
46
|
disconnect: '退出',
|
@@ -120,6 +123,7 @@ function SessionManager({
|
|
120
123
|
// eslint-disable-next-line react/prop-types
|
121
124
|
}, [session?.initialized, session?.loading]);
|
122
125
|
const masterSiteInfo = window.blocklet?.settings?.federated?.master;
|
126
|
+
const currentSiteInfo = window.blocklet;
|
123
127
|
if (!session.user) {
|
124
128
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
125
129
|
children: [showText ? /*#__PURE__*/_jsxs(Button, {
|
@@ -195,7 +199,8 @@ function SessionManager({
|
|
195
199
|
function _onLogout() {
|
196
200
|
session.logout((...args) => {
|
197
201
|
logoutOAuth({
|
198
|
-
session
|
202
|
+
session,
|
203
|
+
hack: true
|
199
204
|
}, ...args).then(() => {
|
200
205
|
onLogout(...args);
|
201
206
|
}).catch(err => {
|
@@ -205,10 +210,28 @@ function SessionManager({
|
|
205
210
|
});
|
206
211
|
});
|
207
212
|
}
|
213
|
+
/**
|
214
|
+
* @name 切换账户
|
215
|
+
* @description 该功能仅在登录后才能使用,目前仅用于切换普通登录和统一登录的账户,所以会增加一些与统一登录相关的逻辑
|
216
|
+
*/
|
208
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
|
+
}
|
209
229
|
session.switchDid((...args) => {
|
210
230
|
setUserOpen(false);
|
211
231
|
onSwitchDid(...args);
|
232
|
+
}, {
|
233
|
+
provider: targetProvider,
|
234
|
+
providerMode: 'paramsFirst'
|
212
235
|
});
|
213
236
|
}
|
214
237
|
function _onSwitchProfile() {
|
@@ -316,25 +339,6 @@ function SessionManager({
|
|
316
339
|
})
|
317
340
|
})]
|
318
341
|
})]
|
319
|
-
}), federatedAccount && !isEmpty(masterSiteInfo) && /*#__PURE__*/_jsx(MenuItem, {
|
320
|
-
className: "session-manager-menu-item",
|
321
|
-
"data-cy": "sessionManager-connectWithFederated",
|
322
|
-
children: /*#__PURE__*/_jsxs(Box, {
|
323
|
-
overflow: "hidden",
|
324
|
-
textOverflow: "ellipsis",
|
325
|
-
children: [/*#__PURE__*/_jsx(SvgIcon, {
|
326
|
-
component: ConnectWithoutContactIcon,
|
327
|
-
className: "session-manager-menu-icon"
|
328
|
-
}), translation.connectedWith, /*#__PURE__*/_jsx(Link, {
|
329
|
-
ml: 1,
|
330
|
-
href: masterSiteInfo.appUrl,
|
331
|
-
underline: "hover",
|
332
|
-
target: "_blank",
|
333
|
-
title: masterSiteInfo.appName,
|
334
|
-
"aria-label": "Open federated master site url",
|
335
|
-
children: masterSiteInfo.appName
|
336
|
-
})]
|
337
|
-
})
|
338
342
|
}), Array.isArray(menu) && menu.map((menuItem, index) => {
|
339
343
|
const {
|
340
344
|
svgIcon,
|
@@ -366,7 +370,7 @@ function SessionManager({
|
|
366
370
|
component: OpenInIcon,
|
367
371
|
className: "session-manager-menu-icon"
|
368
372
|
}), translation.openInWallet]
|
369
|
-
}), !!switchDid && /*#__PURE__*/_jsxs(MenuItem, {
|
373
|
+
}), !isEmpty(masterSiteInfo) && !!switchDid && /*#__PURE__*/_jsxs(MenuItem, {
|
370
374
|
className: "session-manager-menu-item",
|
371
375
|
onClick: _onSwitchDid,
|
372
376
|
"aria-label": translation.switchDid,
|
@@ -374,7 +378,29 @@ function SessionManager({
|
|
374
378
|
children: [/*#__PURE__*/_jsx(SvgIcon, {
|
375
379
|
component: SwitchDidIcon,
|
376
380
|
className: "session-manager-menu-icon"
|
377
|
-
}),
|
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
|
+
})]
|
378
404
|
}), !!switchProfile && hasBindWallet && session.provider !== 'federated' && /*#__PURE__*/_jsxs(MenuItem, {
|
379
405
|
className: "session-manager-menu-item",
|
380
406
|
onClick: _onSwitchProfile,
|
@@ -70,6 +70,21 @@ function CardSelector(_ref) {
|
|
70
70
|
transform: "translate(".concat(-translateX, "px, 0)")
|
71
71
|
},
|
72
72
|
children: list.map((e, i) => {
|
73
|
+
if (e instanceof Function) {
|
74
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
75
|
+
className: "card-item ".concat(i === selectedId ? 'selected' : ''),
|
76
|
+
style: {
|
77
|
+
width,
|
78
|
+
height,
|
79
|
+
margin: cardSpace / 2
|
80
|
+
}
|
81
|
+
// eslint-disable-next-line react/no-array-index-key
|
82
|
+
,
|
83
|
+
|
84
|
+
onClick: () => selectedItem(i),
|
85
|
+
children: e(i)
|
86
|
+
}, i);
|
87
|
+
}
|
73
88
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
74
89
|
className: "card-item ".concat(i === selectedId ? 'selected' : ''),
|
75
90
|
style: {
|
@@ -90,7 +105,7 @@ function CardSelector(_ref) {
|
|
90
105
|
})
|
91
106
|
});
|
92
107
|
}
|
93
|
-
const Contianer = _styled.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n overflow: hidden;\n mask-image: linear-gradient(to left, transparent, black 3%, black 97%, transparent);\n overflow: hidden;\n .card-container {\n display: flex;\n white-space: nowrap;\n width: max-content;\n transition: all ease 0.3s;\n }\n .card-item {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n cursor: pointer;\n img {\n max-width: 100%;\n max-height: 100%;\n width: auto;\n height: auto;\n outline: #526ded solid 0;\n transition: all ease 0.2s;\n box-shadow: rgba(0, 0, 0, 0.2) 0 0 10px;\n }\n &.selected {\n cursor: default;\n img {\n outline: #526ded solid 5px;\n }\n }\n }\n"])));
|
108
|
+
const Contianer = _styled.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n overflow: hidden;\n mask-image: linear-gradient(to left, transparent, black 3%, black 97%, transparent);\n overflow: hidden;\n .card-container {\n display: flex;\n white-space: nowrap;\n width: max-content;\n transition: all ease 0.3s;\n }\n .card-item {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n cursor: pointer;\n img,\n svg {\n max-width: 100%;\n max-height: 100%;\n width: auto;\n height: auto;\n outline: #526ded solid 0;\n transition: all ease 0.2s;\n box-shadow: rgba(0, 0, 0, 0.2) 0 0 10px;\n }\n &.selected {\n cursor: default;\n img,\n svg {\n outline: #526ded solid 5px;\n }\n }\n }\n"])));
|
94
109
|
CardSelector.propTypes = {
|
95
110
|
list: _propTypes.default.array,
|
96
111
|
width: _propTypes.default.number,
|
package/lib/Dialog/confirm.js
CHANGED
@@ -4,7 +4,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
5
5
|
});
|
6
6
|
exports.default = Confirm;
|
7
|
+
exports.useConfirm = useConfirm;
|
7
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
9
|
+
var _react = require("react");
|
10
|
+
var _ahooks = require("ahooks");
|
11
|
+
var _noop = _interopRequireDefault(require("lodash/noop"));
|
12
|
+
var _context = require("../Locale/context");
|
8
13
|
var _Button = _interopRequireDefault(require("../Button"));
|
9
14
|
var _dialog = _interopRequireDefault(require("./dialog"));
|
10
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
@@ -19,7 +24,7 @@ const _excluded = ["title", "children", "onConfirm", "onCancel", "showCancelButt
|
|
19
24
|
@property {boolean} [showCancelButton=true]
|
20
25
|
@property {{text: string, props?: import('../Button/wrap').ButtonProps}} [confirmButton={text: 'Confirm'}]
|
21
26
|
@property {{text: string, props?: import('../Button/wrap').ButtonProps}} [cancelButton={text: 'Cancel'}]
|
22
|
-
@property {import('@mui/material').PaperProps} [PaperProps={}]
|
27
|
+
@property {import('@mui/material').PaperProps} [PaperProps={}]
|
23
28
|
*/
|
24
29
|
// 注意排在 {...rest} 之后的 props 优先级更高
|
25
30
|
/**
|
@@ -99,4 +104,105 @@ Confirm.defaultProps = {
|
|
99
104
|
text: 'Cancel'
|
100
105
|
},
|
101
106
|
PaperProps: {}
|
102
|
-
};
|
107
|
+
};
|
108
|
+
const ConfirmHolder = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
109
|
+
const {
|
110
|
+
t
|
111
|
+
} = (0, _react.useContext)(_context.LocaleContext);
|
112
|
+
const state = (0, _ahooks.useReactive)({
|
113
|
+
show: false,
|
114
|
+
title: '',
|
115
|
+
content: '',
|
116
|
+
onConfirm: _noop.default,
|
117
|
+
onCancel: _noop.default,
|
118
|
+
loading: false
|
119
|
+
});
|
120
|
+
const open = (0, _ahooks.useMemoizedFn)(function () {
|
121
|
+
let params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
122
|
+
state.show = true;
|
123
|
+
state.title = params.title;
|
124
|
+
state.content = params.content;
|
125
|
+
state.onConfirm = params.onConfirm || _noop.default;
|
126
|
+
state.onCancel = params.onCancel || _noop.default;
|
127
|
+
state.loading = false;
|
128
|
+
});
|
129
|
+
const reset = (0, _ahooks.useMemoizedFn)(() => {
|
130
|
+
state.title = '';
|
131
|
+
state.content = '';
|
132
|
+
state.onConfirm = _noop.default;
|
133
|
+
state.onCancel = _noop.default;
|
134
|
+
});
|
135
|
+
const close = (0, _ahooks.useMemoizedFn)(() => {
|
136
|
+
state.show = false;
|
137
|
+
setTimeout(() => {
|
138
|
+
reset();
|
139
|
+
}, 300);
|
140
|
+
});
|
141
|
+
const onCancel = (0, _ahooks.useMemoizedFn)(() => {
|
142
|
+
close();
|
143
|
+
state === null || state === void 0 ? void 0 : state.onCancel();
|
144
|
+
}, []);
|
145
|
+
const onConfirm = (0, _ahooks.useMemoizedFn)(async () => {
|
146
|
+
state.loading = true;
|
147
|
+
try {
|
148
|
+
await (state === null || state === void 0 ? void 0 : state.onConfirm(close));
|
149
|
+
} finally {
|
150
|
+
state.loading = false;
|
151
|
+
}
|
152
|
+
}, []);
|
153
|
+
(0, _react.useImperativeHandle)(ref, () => {
|
154
|
+
return {
|
155
|
+
open,
|
156
|
+
close
|
157
|
+
};
|
158
|
+
}, [open, close]);
|
159
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Confirm, {
|
160
|
+
open: state.show,
|
161
|
+
title: state.title,
|
162
|
+
onConfirm: onConfirm,
|
163
|
+
onCancel: onCancel,
|
164
|
+
confirmButton: {
|
165
|
+
text: t('common.confirm'),
|
166
|
+
props: {
|
167
|
+
variant: 'contained',
|
168
|
+
color: 'primary',
|
169
|
+
loading: state.loading
|
170
|
+
}
|
171
|
+
},
|
172
|
+
cancelButton: {
|
173
|
+
text: t('common.cancel'),
|
174
|
+
props: {
|
175
|
+
variant: 'outlined',
|
176
|
+
color: 'primary'
|
177
|
+
}
|
178
|
+
},
|
179
|
+
children: state.content
|
180
|
+
});
|
181
|
+
});
|
182
|
+
function useConfirm() {
|
183
|
+
const confirmRef = (0, _react.useRef)(null);
|
184
|
+
const open = (0, _ahooks.useMemoizedFn)(function () {
|
185
|
+
var _confirmRef$current;
|
186
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
187
|
+
args[_key] = arguments[_key];
|
188
|
+
}
|
189
|
+
(_confirmRef$current = confirmRef.current) === null || _confirmRef$current === void 0 ? void 0 : _confirmRef$current.open(...args);
|
190
|
+
});
|
191
|
+
const close = (0, _ahooks.useMemoizedFn)(function () {
|
192
|
+
var _confirmRef$current2;
|
193
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
194
|
+
args[_key2] = arguments[_key2];
|
195
|
+
}
|
196
|
+
(_confirmRef$current2 = confirmRef.current) === null || _confirmRef$current2 === void 0 ? void 0 : _confirmRef$current2.close(...args);
|
197
|
+
});
|
198
|
+
const confirmApi = {
|
199
|
+
open,
|
200
|
+
close
|
201
|
+
};
|
202
|
+
return {
|
203
|
+
confirmHolder: /*#__PURE__*/(0, _jsxRuntime.jsx)(ConfirmHolder, {
|
204
|
+
ref: confirmRef
|
205
|
+
}),
|
206
|
+
confirmApi
|
207
|
+
};
|
208
|
+
}
|
package/lib/Dialog/index.js
CHANGED
@@ -15,6 +15,14 @@ Object.defineProperty(exports, "default", {
|
|
15
15
|
return _dialog.default;
|
16
16
|
}
|
17
17
|
});
|
18
|
+
Object.defineProperty(exports, "useConfirm", {
|
19
|
+
enumerable: true,
|
20
|
+
get: function get() {
|
21
|
+
return _confirm.useConfirm;
|
22
|
+
}
|
23
|
+
});
|
18
24
|
var _dialog = _interopRequireDefault(require("./dialog"));
|
19
|
-
var _confirm =
|
25
|
+
var _confirm = _interopRequireWildcard(require("./confirm"));
|
26
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
27
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
20
28
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
package/lib/Locale/selector.js
CHANGED
@@ -6,21 +6,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
exports.default = LocaleSelector;
|
7
7
|
var _react = require("react");
|
8
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
9
|
-
var
|
10
|
-
var _Typography = _interopRequireDefault(require("@mui/material/Typography"));
|
11
|
-
var _IconButton = _interopRequireDefault(require("@mui/material/IconButton"));
|
12
|
-
var _ClickAwayListener = _interopRequireDefault(require("@mui/material/ClickAwayListener"));
|
13
|
-
var _Popper = _interopRequireDefault(require("@mui/material/Popper"));
|
14
|
-
var _MenuItem = _interopRequireDefault(require("@mui/material/MenuItem"));
|
15
|
-
var _MenuList = _interopRequireDefault(require("@mui/material/MenuList"));
|
16
|
-
var _Box = _interopRequireDefault(require("@mui/material/Box"));
|
9
|
+
var _material = require("@mui/material");
|
17
10
|
var _Check = _interopRequireDefault(require("@mui/icons-material/Check"));
|
18
11
|
var _Globe = _interopRequireDefault(require("@arcblock/icons/lib/Globe"));
|
19
12
|
var _Util = require("../Util");
|
20
13
|
var _context = require("./context");
|
21
14
|
var _Theme = require("../Theme");
|
22
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
23
|
-
var _templateObject;
|
16
|
+
var _templateObject, _templateObject2;
|
24
17
|
const _excluded = ["showText", "popperProps", "popperType", "icon", "size"];
|
25
18
|
/* eslint-disable react/jsx-no-bind */
|
26
19
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
@@ -65,7 +58,7 @@ function LocaleSelector(props) {
|
|
65
58
|
}
|
66
59
|
setOpen(false);
|
67
60
|
};
|
68
|
-
const ButtonComponent = showText ?
|
61
|
+
const ButtonComponent = showText ? _material.Button : _material.IconButton;
|
69
62
|
const handleEventProps = popperType === 'hover' ? {
|
70
63
|
onMouseEnter: () => {
|
71
64
|
setOpen(true);
|
@@ -100,31 +93,31 @@ function LocaleSelector(props) {
|
|
100
93
|
className: "trigger",
|
101
94
|
role: "button",
|
102
95
|
"aria-label": "Locale selector button",
|
103
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(
|
96
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
104
97
|
display: "flex",
|
105
98
|
alignItems: "center",
|
106
|
-
children: [renderIcon, showText ? /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
99
|
+
children: [renderIcon, showText ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
|
107
100
|
component: "strong",
|
108
101
|
className: "trigger-text",
|
109
102
|
children: languages.find(x => x.code === locale).name
|
110
103
|
}) : '']
|
111
104
|
})
|
112
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
105
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledPopper, _objectSpread(_objectSpread({
|
113
106
|
open: open,
|
114
107
|
anchorEl: anchorEl.current
|
115
108
|
}, popperProps), {}, {
|
116
109
|
disablePortal: true,
|
117
110
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
118
111
|
className: "locales",
|
119
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
112
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.ClickAwayListener, {
|
120
113
|
onClickAway: onClose,
|
121
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
114
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuList, {
|
122
115
|
children: languages.map(_ref => {
|
123
116
|
let {
|
124
117
|
code,
|
125
118
|
name
|
126
119
|
} = _ref;
|
127
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(
|
120
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
|
128
121
|
className: "locale-item",
|
129
122
|
onClick: () => onSelect(code, name),
|
130
123
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Check.default, {
|
@@ -157,4 +150,10 @@ LocaleSelector.defaultProps = {
|
|
157
150
|
};
|
158
151
|
const Div = (0, _Theme.styled)('div', {
|
159
152
|
shouldForwardProp: prop => prop !== 'dark'
|
160
|
-
})(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: inline-block;\n\n .trigger {\n display: flex;\n flex-direction: column;\n justify-content: center;\n font-size: 14px;\n white-space: nowrap;\n\n .trigger-text {\n margin-left: 5px;\n font-size: 14px;\n color: ", ";\n }\n }\n\n .locales {\n background: ", ";\n box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);\n }\n\n .locale-item {\n font-size: 16px;\n font-style: normal;\n font-stretch: normal;\n line-height: normal;\n letter-spacing: 2px;\n text-align: center;\n color: ", ";\n cursor: pointer;\n display: flex;\n padding: 16px;\n align-items: center;\n .check-icon {\n visibility: hidden;\n margin-right: 4px;\n }\n .check-icon-visible {\n visibility: visible;\n }\n }\n"])), props => (0, _Util.getColor)(props), props => (0, _Util.getBackground)(props), props => (0, _Util.getColor)(props));
|
153
|
+
})(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: inline-block;\n\n .trigger {\n display: flex;\n flex-direction: column;\n justify-content: center;\n font-size: 14px;\n white-space: nowrap;\n\n .trigger-text {\n margin-left: 5px;\n font-size: 14px;\n color: ", ";\n }\n }\n\n .locales {\n background: ", ";\n box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);\n }\n\n .locale-item {\n font-size: 16px;\n font-style: normal;\n font-stretch: normal;\n line-height: normal;\n letter-spacing: 2px;\n text-align: center;\n color: ", ";\n cursor: pointer;\n display: flex;\n padding: 16px;\n align-items: center;\n .check-icon {\n visibility: hidden;\n margin-right: 4px;\n }\n .check-icon-visible {\n visibility: visible;\n }\n }\n"])), props => (0, _Util.getColor)(props), props => (0, _Util.getBackground)(props), props => (0, _Util.getColor)(props));
|
154
|
+
const StyledPopper = (0, _Theme.styled)(_material.Popper)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n z-index: ", ";\n"])), _ref2 => {
|
155
|
+
let {
|
156
|
+
theme
|
157
|
+
} = _ref2;
|
158
|
+
return theme.zIndex.tooltip + 10;
|
159
|
+
});
|
@@ -27,7 +27,7 @@ const translations = {
|
|
27
27
|
member
|
28
28
|
} = _ref;
|
29
29
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
30
|
-
children: ["
|
30
|
+
children: ["Connect ", member, " with ", master, " account"]
|
31
31
|
});
|
32
32
|
},
|
33
33
|
connect: 'Connect Account',
|
@@ -72,6 +72,14 @@ function FederatedLoginDetecter(_ref3) {
|
|
72
72
|
mode: userInfo ? 'auto' : 'manual'
|
73
73
|
});
|
74
74
|
}, [session, userInfo, _locale]);
|
75
|
+
let appLogoUrl;
|
76
|
+
if (siteInfo) {
|
77
|
+
appLogoUrl = new URL(siteInfo.appLogo, siteInfo.appUrl);
|
78
|
+
appLogoUrl.searchParams.set('imageFilter', 'resize');
|
79
|
+
// HACK: 保持跟其他地方使用的尺寸一致,可以复用同一资源的缓存,减少网络请求
|
80
|
+
appLogoUrl.searchParams.set('w', '80');
|
81
|
+
appLogoUrl.searchParams.set('h', '80');
|
82
|
+
}
|
75
83
|
return siteInfo && /*#__PURE__*/(0, _jsxRuntime.jsx)(_userPopper.default, {
|
76
84
|
open: federatedLoginOpen,
|
77
85
|
anchorEl: anchorEl,
|
@@ -86,7 +94,7 @@ function FederatedLoginDetecter(_ref3) {
|
|
86
94
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
|
87
95
|
component: "img",
|
88
96
|
mr: 2,
|
89
|
-
src:
|
97
|
+
src: appLogoUrl.href,
|
90
98
|
alt: siteInfo.appName,
|
91
99
|
width: "30px",
|
92
100
|
height: "30px"
|
@@ -10,15 +10,14 @@ var _material = require("@mui/material");
|
|
10
10
|
var _PersonOutline = _interopRequireDefault(require("@mui/icons-material/PersonOutline"));
|
11
11
|
var _Link = _interopRequireDefault(require("@mui/icons-material/Link"));
|
12
12
|
var _VpnKeyOutlined = _interopRequireDefault(require("@mui/icons-material/VpnKeyOutlined"));
|
13
|
-
var _ConnectWithoutContact = _interopRequireDefault(require("@mui/icons-material/ConnectWithoutContact"));
|
14
13
|
var _ShieldCheck = _interopRequireDefault(require("mdi-material-ui/ShieldCheck"));
|
15
14
|
var _Account = _interopRequireDefault(require("@arcblock/icons/lib/Account"));
|
16
15
|
var _OpenIn = _interopRequireDefault(require("@arcblock/icons/lib/OpenIn"));
|
17
16
|
var _Disconnect = _interopRequireDefault(require("@arcblock/icons/lib/Disconnect"));
|
18
17
|
var _Switch = _interopRequireDefault(require("@arcblock/icons/lib/Switch"));
|
19
18
|
var _useBrowser = _interopRequireDefault(require("@arcblock/react-hooks/lib/useBrowser"));
|
20
|
-
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
21
19
|
var _noop = _interopRequireDefault(require("lodash/noop"));
|
20
|
+
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
22
21
|
var _Avatar = _interopRequireDefault(require("../Avatar"));
|
23
22
|
var _Address = _interopRequireDefault(require("../Address"));
|
24
23
|
var _Util = require("../Util");
|
@@ -39,7 +38,9 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
|
|
39
38
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
40
39
|
const translations = {
|
41
40
|
en: {
|
41
|
+
account: 'account',
|
42
42
|
switchDid: 'Switch DID',
|
43
|
+
switchTo: 'Switch to',
|
43
44
|
switchProfile: 'Switch Profile',
|
44
45
|
switchPassport: 'Switch Passport',
|
45
46
|
disconnect: 'Disconnect',
|
@@ -51,7 +52,9 @@ const translations = {
|
|
51
52
|
connectedWith: 'Connected with'
|
52
53
|
},
|
53
54
|
zh: {
|
55
|
+
account: '账号',
|
54
56
|
switchDid: '切换账户',
|
57
|
+
switchTo: '切换至',
|
55
58
|
switchProfile: '切换用户信息',
|
56
59
|
switchPassport: '切换通行证',
|
57
60
|
disconnect: '退出',
|
@@ -145,6 +148,7 @@ function SessionManager(_ref) {
|
|
145
148
|
// eslint-disable-next-line react/prop-types
|
146
149
|
}, [session === null || session === void 0 ? void 0 : session.initialized, session === null || session === void 0 ? void 0 : session.loading]);
|
147
150
|
const masterSiteInfo = (_window$blocklet = window.blocklet) === null || _window$blocklet === void 0 ? void 0 : (_window$blocklet$sett = _window$blocklet.settings) === null || _window$blocklet$sett === void 0 ? void 0 : (_window$blocklet$sett2 = _window$blocklet$sett.federated) === null || _window$blocklet$sett2 === void 0 ? void 0 : _window$blocklet$sett2.master;
|
151
|
+
const currentSiteInfo = window.blocklet;
|
148
152
|
if (!session.user) {
|
149
153
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
150
154
|
children: [showText ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Button, _objectSpread(_objectSpread({
|
@@ -223,7 +227,8 @@ function SessionManager(_ref) {
|
|
223
227
|
args[_key] = arguments[_key];
|
224
228
|
}
|
225
229
|
logoutOAuth({
|
226
|
-
session
|
230
|
+
session,
|
231
|
+
hack: true
|
227
232
|
}, ...args).then(() => {
|
228
233
|
onLogout(...args);
|
229
234
|
}).catch(err => {
|
@@ -233,10 +238,28 @@ function SessionManager(_ref) {
|
|
233
238
|
});
|
234
239
|
});
|
235
240
|
}
|
241
|
+
/**
|
242
|
+
* @name 切换账户
|
243
|
+
* @description 该功能仅在登录后才能使用,目前仅用于切换普通登录和统一登录的账户,所以会增加一些与统一登录相关的逻辑
|
244
|
+
*/
|
236
245
|
function _onSwitchDid() {
|
246
|
+
const {
|
247
|
+
provider,
|
248
|
+
user
|
249
|
+
} = session;
|
250
|
+
if (!user) return;
|
251
|
+
let targetProvider = provider;
|
252
|
+
if (provider === 'federated') {
|
253
|
+
targetProvider = 'wallet';
|
254
|
+
} else if (['auth0', 'wallet'].includes(provider)) {
|
255
|
+
targetProvider = 'federated';
|
256
|
+
}
|
237
257
|
session.switchDid(function () {
|
238
258
|
setUserOpen(false);
|
239
259
|
onSwitchDid(...arguments);
|
260
|
+
}, {
|
261
|
+
provider: targetProvider,
|
262
|
+
providerMode: 'paramsFirst'
|
240
263
|
});
|
241
264
|
}
|
242
265
|
function _onSwitchProfile() {
|
@@ -344,25 +367,6 @@ function SessionManager(_ref) {
|
|
344
367
|
})
|
345
368
|
})]
|
346
369
|
})]
|
347
|
-
}), federatedAccount && !(0, _isEmpty.default)(masterSiteInfo) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, {
|
348
|
-
className: "session-manager-menu-item",
|
349
|
-
"data-cy": "sessionManager-connectWithFederated",
|
350
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
351
|
-
overflow: "hidden",
|
352
|
-
textOverflow: "ellipsis",
|
353
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.SvgIcon, {
|
354
|
-
component: _ConnectWithoutContact.default,
|
355
|
-
className: "session-manager-menu-icon"
|
356
|
-
}), translation.connectedWith, /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Link, {
|
357
|
-
ml: 1,
|
358
|
-
href: masterSiteInfo.appUrl,
|
359
|
-
underline: "hover",
|
360
|
-
target: "_blank",
|
361
|
-
title: masterSiteInfo.appName,
|
362
|
-
"aria-label": "Open federated master site url",
|
363
|
-
children: masterSiteInfo.appName
|
364
|
-
})]
|
365
|
-
})
|
366
370
|
}), Array.isArray(menu) && menu.map((menuItem, index) => {
|
367
371
|
const {
|
368
372
|
svgIcon
|
@@ -395,7 +399,7 @@ function SessionManager(_ref) {
|
|
395
399
|
component: _OpenIn.default,
|
396
400
|
className: "session-manager-menu-icon"
|
397
401
|
}), translation.openInWallet]
|
398
|
-
}), !!switchDid && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
|
402
|
+
}), !(0, _isEmpty.default)(masterSiteInfo) && !!switchDid && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
|
399
403
|
className: "session-manager-menu-item",
|
400
404
|
onClick: _onSwitchDid,
|
401
405
|
"aria-label": translation.switchDid,
|
@@ -403,7 +407,29 @@ function SessionManager(_ref) {
|
|
403
407
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.SvgIcon, {
|
404
408
|
component: _Switch.default,
|
405
409
|
className: "session-manager-menu-icon"
|
406
|
-
}),
|
410
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
411
|
+
sx: {
|
412
|
+
whiteSpace: 'normal',
|
413
|
+
wordBreak: 'break-all'
|
414
|
+
},
|
415
|
+
children: [translation.switchTo, session.provider === 'federated' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Link, {
|
416
|
+
mx: 1,
|
417
|
+
href: currentSiteInfo.appUrl,
|
418
|
+
underline: "hover",
|
419
|
+
target: "_blank",
|
420
|
+
title: currentSiteInfo.appName,
|
421
|
+
"aria-label": "Open current site url",
|
422
|
+
children: currentSiteInfo.appName
|
423
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Link, {
|
424
|
+
mx: 1,
|
425
|
+
href: masterSiteInfo.appUrl,
|
426
|
+
underline: "hover",
|
427
|
+
target: "_blank",
|
428
|
+
title: masterSiteInfo.appName,
|
429
|
+
"aria-label": "Open federated master site url",
|
430
|
+
children: masterSiteInfo.appName
|
431
|
+
}), translation.account]
|
432
|
+
})]
|
407
433
|
}), !!switchProfile && hasBindWallet && session.provider !== 'federated' && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
|
408
434
|
className: "session-manager-menu-item",
|
409
435
|
onClick: _onSwitchProfile,
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.7.
|
3
|
+
"version": "2.7.15",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -318,11 +318,11 @@
|
|
318
318
|
"peerDependencies": {
|
319
319
|
"react": ">=18.1.0"
|
320
320
|
},
|
321
|
-
"gitHead": "
|
321
|
+
"gitHead": "a40ed26cfd0cbf892b00f98c773eff8ad7a50570",
|
322
322
|
"dependencies": {
|
323
323
|
"@arcblock/did-motif": "^1.1.13",
|
324
|
-
"@arcblock/icons": "^2.7.
|
325
|
-
"@arcblock/react-hooks": "^2.7.
|
324
|
+
"@arcblock/icons": "^2.7.15",
|
325
|
+
"@arcblock/react-hooks": "^2.7.15",
|
326
326
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
327
327
|
"@emotion/react": "^11.10.4",
|
328
328
|
"@emotion/styled": "^11.10.4",
|
@@ -54,6 +54,18 @@ export default function CardSelector({ list, width, height, cardSpace, onSelect,
|
|
54
54
|
<Contianer ref={outterCon} onTouchStart={touchstart} onTouchEnd={touchend}>
|
55
55
|
<div className="card-container" style={{ transform: `translate(${-translateX}px, 0)` }}>
|
56
56
|
{list.map((e, i) => {
|
57
|
+
if (e instanceof Function) {
|
58
|
+
return (
|
59
|
+
<div
|
60
|
+
className={`card-item ${i === selectedId ? 'selected' : ''}`}
|
61
|
+
style={{ width, height, margin: cardSpace / 2 }}
|
62
|
+
// eslint-disable-next-line react/no-array-index-key
|
63
|
+
key={i}
|
64
|
+
onClick={() => selectedItem(i)}>
|
65
|
+
{e(i)}
|
66
|
+
</div>
|
67
|
+
);
|
68
|
+
}
|
57
69
|
return (
|
58
70
|
<div
|
59
71
|
className={`card-item ${i === selectedId ? 'selected' : ''}`}
|
@@ -86,7 +98,8 @@ const Contianer = styled.div`
|
|
86
98
|
align-items: center;
|
87
99
|
flex-shrink: 0;
|
88
100
|
cursor: pointer;
|
89
|
-
img
|
101
|
+
img,
|
102
|
+
svg {
|
90
103
|
max-width: 100%;
|
91
104
|
max-height: 100%;
|
92
105
|
width: auto;
|
@@ -97,7 +110,8 @@ const Contianer = styled.div`
|
|
97
110
|
}
|
98
111
|
&.selected {
|
99
112
|
cursor: default;
|
100
|
-
img
|
113
|
+
img,
|
114
|
+
svg {
|
101
115
|
outline: #526ded solid 5px;
|
102
116
|
}
|
103
117
|
}
|
package/src/Dialog/confirm.js
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
import PropTypes from 'prop-types';
|
2
|
+
import { useContext, forwardRef, useRef, useImperativeHandle } from 'react';
|
3
|
+
import { useMemoizedFn, useReactive } from 'ahooks';
|
4
|
+
import noop from 'lodash/noop';
|
5
|
+
|
6
|
+
import { LocaleContext } from '../Locale/context';
|
2
7
|
import Button from '../Button';
|
3
8
|
import Dialog from './dialog';
|
4
9
|
|
@@ -12,7 +17,7 @@ import Dialog from './dialog';
|
|
12
17
|
@property {boolean} [showCancelButton=true]
|
13
18
|
@property {{text: string, props?: import('../Button/wrap').ButtonProps}} [confirmButton={text: 'Confirm'}]
|
14
19
|
@property {{text: string, props?: import('../Button/wrap').ButtonProps}} [cancelButton={text: 'Cancel'}]
|
15
|
-
@property {import('@mui/material').PaperProps} [PaperProps={}]
|
20
|
+
@property {import('@mui/material').PaperProps} [PaperProps={}]
|
16
21
|
*/
|
17
22
|
|
18
23
|
// 注意排在 {...rest} 之后的 props 优先级更高
|
@@ -91,3 +96,103 @@ Confirm.defaultProps = {
|
|
91
96
|
},
|
92
97
|
PaperProps: {},
|
93
98
|
};
|
99
|
+
|
100
|
+
const ConfirmHolder = forwardRef((props, ref) => {
|
101
|
+
const { t } = useContext(LocaleContext);
|
102
|
+
|
103
|
+
const state = useReactive({
|
104
|
+
show: false,
|
105
|
+
title: '',
|
106
|
+
content: '',
|
107
|
+
onConfirm: noop,
|
108
|
+
onCancel: noop,
|
109
|
+
loading: false,
|
110
|
+
});
|
111
|
+
const open = useMemoizedFn((params = {}) => {
|
112
|
+
state.show = true;
|
113
|
+
state.title = params.title;
|
114
|
+
state.content = params.content;
|
115
|
+
state.onConfirm = params.onConfirm || noop;
|
116
|
+
state.onCancel = params.onCancel || noop;
|
117
|
+
state.loading = false;
|
118
|
+
});
|
119
|
+
const reset = useMemoizedFn(() => {
|
120
|
+
state.title = '';
|
121
|
+
state.content = '';
|
122
|
+
state.onConfirm = noop;
|
123
|
+
state.onCancel = noop;
|
124
|
+
});
|
125
|
+
const close = useMemoizedFn(() => {
|
126
|
+
state.show = false;
|
127
|
+
setTimeout(() => {
|
128
|
+
reset();
|
129
|
+
}, 300);
|
130
|
+
});
|
131
|
+
const onCancel = useMemoizedFn(() => {
|
132
|
+
close();
|
133
|
+
state?.onCancel();
|
134
|
+
}, []);
|
135
|
+
const onConfirm = useMemoizedFn(async () => {
|
136
|
+
state.loading = true;
|
137
|
+
try {
|
138
|
+
await state?.onConfirm(close);
|
139
|
+
} finally {
|
140
|
+
state.loading = false;
|
141
|
+
}
|
142
|
+
}, []);
|
143
|
+
useImperativeHandle(
|
144
|
+
ref,
|
145
|
+
() => {
|
146
|
+
return {
|
147
|
+
open,
|
148
|
+
close,
|
149
|
+
};
|
150
|
+
},
|
151
|
+
[open, close]
|
152
|
+
);
|
153
|
+
|
154
|
+
return (
|
155
|
+
<Confirm
|
156
|
+
open={state.show}
|
157
|
+
title={state.title}
|
158
|
+
onConfirm={onConfirm}
|
159
|
+
onCancel={onCancel}
|
160
|
+
confirmButton={{
|
161
|
+
text: t('common.confirm'),
|
162
|
+
props: {
|
163
|
+
variant: 'contained',
|
164
|
+
color: 'primary',
|
165
|
+
loading: state.loading,
|
166
|
+
},
|
167
|
+
}}
|
168
|
+
cancelButton={{
|
169
|
+
text: t('common.cancel'),
|
170
|
+
props: {
|
171
|
+
variant: 'outlined',
|
172
|
+
color: 'primary',
|
173
|
+
},
|
174
|
+
}}>
|
175
|
+
{state.content}
|
176
|
+
</Confirm>
|
177
|
+
);
|
178
|
+
});
|
179
|
+
|
180
|
+
export function useConfirm() {
|
181
|
+
const confirmRef = useRef(null);
|
182
|
+
|
183
|
+
const open = useMemoizedFn((...args) => {
|
184
|
+
confirmRef.current?.open(...args);
|
185
|
+
});
|
186
|
+
const close = useMemoizedFn((...args) => {
|
187
|
+
confirmRef.current?.close(...args);
|
188
|
+
});
|
189
|
+
const confirmApi = {
|
190
|
+
open,
|
191
|
+
close,
|
192
|
+
};
|
193
|
+
|
194
|
+
return {
|
195
|
+
confirmHolder: <ConfirmHolder ref={confirmRef} />,
|
196
|
+
confirmApi,
|
197
|
+
};
|
198
|
+
}
|
package/src/Dialog/index.js
CHANGED
@@ -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
|
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
|
-
<
|
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
|
-
</
|
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
|
+
`;
|
@@ -18,7 +18,7 @@ const translations = {
|
|
18
18
|
useToConnect({ master, member }) {
|
19
19
|
return (
|
20
20
|
<>
|
21
|
-
|
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: (
|
@@ -6,15 +6,14 @@ import { Box, IconButton, MenuList, MenuItem, SvgIcon, Button, Chip, Link, Circu
|
|
6
6
|
import SwitchProfileIcon from '@mui/icons-material/PersonOutline';
|
7
7
|
import BindWalletIcon from '@mui/icons-material/Link';
|
8
8
|
import SwitchPassportIcon from '@mui/icons-material/VpnKeyOutlined';
|
9
|
-
import ConnectWithoutContactIcon from '@mui/icons-material/ConnectWithoutContact';
|
10
9
|
import ShieldCheck from 'mdi-material-ui/ShieldCheck';
|
11
10
|
import AccountIcon from '@arcblock/icons/lib/Account';
|
12
11
|
import OpenInIcon from '@arcblock/icons/lib/OpenIn';
|
13
12
|
import DisconnectIcon from '@arcblock/icons/lib/Disconnect';
|
14
13
|
import SwitchDidIcon from '@arcblock/icons/lib/Switch';
|
15
14
|
import useBrowser from '@arcblock/react-hooks/lib/useBrowser';
|
16
|
-
import isEmpty from 'lodash/isEmpty';
|
17
15
|
import noop from 'lodash/noop';
|
16
|
+
import isEmpty from 'lodash/isEmpty';
|
18
17
|
|
19
18
|
import DidAvatar from '../Avatar';
|
20
19
|
import DidAddress from '../Address';
|
@@ -24,7 +23,9 @@ import UserPopper from './user-popper';
|
|
24
23
|
|
25
24
|
const translations = {
|
26
25
|
en: {
|
26
|
+
account: 'account',
|
27
27
|
switchDid: 'Switch DID',
|
28
|
+
switchTo: 'Switch to',
|
28
29
|
switchProfile: 'Switch Profile',
|
29
30
|
switchPassport: 'Switch Passport',
|
30
31
|
disconnect: 'Disconnect',
|
@@ -36,7 +37,9 @@ const translations = {
|
|
36
37
|
connectedWith: 'Connected with',
|
37
38
|
},
|
38
39
|
zh: {
|
40
|
+
account: '账号',
|
39
41
|
switchDid: '切换账户',
|
42
|
+
switchTo: '切换至',
|
40
43
|
switchProfile: '切换用户信息',
|
41
44
|
switchPassport: '切换通行证',
|
42
45
|
disconnect: '退出',
|
@@ -118,6 +121,7 @@ function SessionManager({
|
|
118
121
|
}, [session?.initialized, session?.loading]);
|
119
122
|
|
120
123
|
const masterSiteInfo = window.blocklet?.settings?.federated?.master;
|
124
|
+
const currentSiteInfo = window.blocklet;
|
121
125
|
|
122
126
|
if (!session.user) {
|
123
127
|
return (
|
@@ -177,7 +181,7 @@ function SessionManager({
|
|
177
181
|
}
|
178
182
|
function _onLogout() {
|
179
183
|
session.logout((...args) => {
|
180
|
-
logoutOAuth({ session }, ...args)
|
184
|
+
logoutOAuth({ session, hack: true }, ...args)
|
181
185
|
.then(() => {
|
182
186
|
onLogout(...args);
|
183
187
|
})
|
@@ -189,11 +193,29 @@ function SessionManager({
|
|
189
193
|
});
|
190
194
|
});
|
191
195
|
}
|
196
|
+
/**
|
197
|
+
* @name 切换账户
|
198
|
+
* @description 该功能仅在登录后才能使用,目前仅用于切换普通登录和统一登录的账户,所以会增加一些与统一登录相关的逻辑
|
199
|
+
*/
|
192
200
|
function _onSwitchDid() {
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
201
|
+
const { provider, user } = session;
|
202
|
+
if (!user) return;
|
203
|
+
let targetProvider = provider;
|
204
|
+
if (provider === 'federated') {
|
205
|
+
targetProvider = 'wallet';
|
206
|
+
} else if (['auth0', 'wallet'].includes(provider)) {
|
207
|
+
targetProvider = 'federated';
|
208
|
+
}
|
209
|
+
session.switchDid(
|
210
|
+
(...args) => {
|
211
|
+
setUserOpen(false);
|
212
|
+
onSwitchDid(...args);
|
213
|
+
},
|
214
|
+
{
|
215
|
+
provider: targetProvider,
|
216
|
+
providerMode: 'paramsFirst',
|
217
|
+
}
|
218
|
+
);
|
197
219
|
}
|
198
220
|
function _onSwitchProfile() {
|
199
221
|
session.switchProfile((...args) => {
|
@@ -274,23 +296,6 @@ function SessionManager({
|
|
274
296
|
)}
|
275
297
|
</div>
|
276
298
|
</div>
|
277
|
-
{federatedAccount && !isEmpty(masterSiteInfo) && (
|
278
|
-
<MenuItem className="session-manager-menu-item" data-cy="sessionManager-connectWithFederated">
|
279
|
-
<Box overflow="hidden" textOverflow="ellipsis">
|
280
|
-
<SvgIcon component={ConnectWithoutContactIcon} className="session-manager-menu-icon" />
|
281
|
-
{translation.connectedWith}
|
282
|
-
<Link
|
283
|
-
ml={1}
|
284
|
-
href={masterSiteInfo.appUrl}
|
285
|
-
underline="hover"
|
286
|
-
target="_blank"
|
287
|
-
title={masterSiteInfo.appName}
|
288
|
-
aria-label="Open federated master site url">
|
289
|
-
{masterSiteInfo.appName}
|
290
|
-
</Link>
|
291
|
-
</Box>
|
292
|
-
</MenuItem>
|
293
|
-
)}
|
294
299
|
{Array.isArray(menu) &&
|
295
300
|
menu.map((menuItem, index) => {
|
296
301
|
const { svgIcon, ...menuProps } = menuItem;
|
@@ -328,14 +333,38 @@ function SessionManager({
|
|
328
333
|
{translation.openInWallet}
|
329
334
|
</MenuItem>
|
330
335
|
)}
|
331
|
-
{!!switchDid && (
|
336
|
+
{!isEmpty(masterSiteInfo) && !!switchDid && (
|
332
337
|
<MenuItem
|
333
338
|
className="session-manager-menu-item"
|
334
339
|
onClick={_onSwitchDid}
|
335
340
|
aria-label={translation.switchDid}
|
336
341
|
data-cy="sessionManager-switch-trigger">
|
337
342
|
<SvgIcon component={SwitchDidIcon} className="session-manager-menu-icon" />
|
338
|
-
{
|
343
|
+
<Box sx={{ whiteSpace: 'normal', wordBreak: 'break-all' }}>
|
344
|
+
{translation.switchTo}
|
345
|
+
{session.provider === 'federated' ? (
|
346
|
+
<Link
|
347
|
+
mx={1}
|
348
|
+
href={currentSiteInfo.appUrl}
|
349
|
+
underline="hover"
|
350
|
+
target="_blank"
|
351
|
+
title={currentSiteInfo.appName}
|
352
|
+
aria-label="Open current site url">
|
353
|
+
{currentSiteInfo.appName}
|
354
|
+
</Link>
|
355
|
+
) : (
|
356
|
+
<Link
|
357
|
+
mx={1}
|
358
|
+
href={masterSiteInfo.appUrl}
|
359
|
+
underline="hover"
|
360
|
+
target="_blank"
|
361
|
+
title={masterSiteInfo.appName}
|
362
|
+
aria-label="Open federated master site url">
|
363
|
+
{masterSiteInfo.appName}
|
364
|
+
</Link>
|
365
|
+
)}
|
366
|
+
{translation.account}
|
367
|
+
</Box>
|
339
368
|
</MenuItem>
|
340
369
|
)}
|
341
370
|
{/* NOTE: federated 登录方式不允许切换 profile */}
|
@@ -71,7 +71,9 @@ UserPopper.defaultProps = {
|
|
71
71
|
};
|
72
72
|
|
73
73
|
const StyledPopper = styled(Popper)`
|
74
|
-
z-index: ${({ theme }) =>
|
74
|
+
z-index: ${({ theme }) => {
|
75
|
+
return theme.zIndex.tooltip;
|
76
|
+
}};
|
75
77
|
.MuiList-root {
|
76
78
|
/* HACK: 需要288px 才能将 did 展示完整 */
|
77
79
|
width: 290px;
|
File without changes
|