@arcblock/ux 2.7.16 → 2.7.17
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/SessionManager/account-item.js +5 -4
- package/es/SessionManager/add-account-item.js +13 -31
- package/es/SessionManager/federated-login-detecter.js +32 -26
- package/es/SessionManager/index.js +44 -57
- package/es/SessionManager/manage-accounts.js +30 -17
- package/es/SessionManager/manage-blocklet.js +12 -4
- package/es/SessionManager/menu-accordion.js +14 -5
- package/es/SessionManager/translation.js +10 -10
- package/es/SessionManager/use-config.js +34 -0
- package/es/SessionManager/user-info.js +51 -43
- package/es/SessionManager/user-popper.js +1 -18
- package/es/Typography/index.js +89 -0
- package/es/Util/federated.js +65 -0
- package/lib/SessionManager/account-item.js +5 -4
- package/lib/SessionManager/add-account-item.js +14 -32
- package/lib/SessionManager/federated-login-detecter.js +33 -26
- package/lib/SessionManager/index.js +45 -58
- package/lib/SessionManager/manage-accounts.js +29 -16
- package/lib/SessionManager/manage-blocklet.js +12 -4
- package/lib/SessionManager/menu-accordion.js +14 -5
- package/lib/SessionManager/translation.js +10 -10
- package/lib/SessionManager/use-config.js +41 -0
- package/lib/SessionManager/user-info.js +50 -42
- package/lib/SessionManager/user-popper.js +1 -6
- package/lib/Typography/index.js +100 -0
- package/lib/Util/federated.js +85 -0
- package/package.json +8 -4
- package/src/SessionManager/account-item.jsx +6 -8
- package/src/SessionManager/add-account-item.jsx +12 -30
- package/src/SessionManager/federated-login-detecter.jsx +39 -26
- package/src/SessionManager/index.jsx +48 -68
- package/src/SessionManager/manage-accounts.jsx +27 -13
- package/src/SessionManager/manage-blocklet.jsx +8 -2
- package/src/SessionManager/menu-accordion.jsx +10 -3
- package/src/SessionManager/translation.js +10 -10
- package/src/SessionManager/use-config.js +33 -0
- package/src/SessionManager/user-info.jsx +34 -34
- package/src/SessionManager/user-popper.jsx +1 -16
- package/src/Typography/index.jsx +79 -0
- package/src/Util/federated.js +73 -0
- package/es/SessionManager/use-accounts.js +0 -19
- package/lib/SessionManager/use-accounts.js +0 -25
- package/src/SessionManager/use-accounts.js +0 -18
@@ -0,0 +1,100 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = Typography;
|
7
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
8
|
+
var _material = require("@mui/material");
|
9
|
+
var _ahooks = require("ahooks");
|
10
|
+
var _react = require("react");
|
11
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
12
|
+
const _excluded = ["minFontSize", "fontSize", "children", "sx"];
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
14
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
15
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
16
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
17
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
18
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
19
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
20
|
+
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; }
|
21
|
+
function Typography(_ref) {
|
22
|
+
let {
|
23
|
+
minFontSize,
|
24
|
+
fontSize,
|
25
|
+
children,
|
26
|
+
sx
|
27
|
+
} = _ref,
|
28
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
29
|
+
const refMock = (0, _react.useRef)(null);
|
30
|
+
const refContainer = (0, _react.useRef)(null);
|
31
|
+
const state = (0, _ahooks.useReactive)({
|
32
|
+
fontSize,
|
33
|
+
loading: true,
|
34
|
+
initialSize: undefined
|
35
|
+
});
|
36
|
+
const mockSize = (0, _ahooks.useSize)(refMock.current);
|
37
|
+
const containerSize = (0, _ahooks.useSize)(refContainer.current);
|
38
|
+
(0, _react.useEffect)(() => {
|
39
|
+
if (state.loading) {
|
40
|
+
if (fontSize === 'auto') {
|
41
|
+
if (mockSize && !state.initialSize) {
|
42
|
+
const styleSize = getComputedStyle(refMock.current).fontSize;
|
43
|
+
state.initialSize = Number(styleSize.replace('px', ''));
|
44
|
+
state.fontSize = state.initialSize;
|
45
|
+
}
|
46
|
+
if (containerSize && mockSize) {
|
47
|
+
if (containerSize.width < mockSize.width && state.fontSize > minFontSize) {
|
48
|
+
state.fontSize--;
|
49
|
+
} else {
|
50
|
+
state.loading = false;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
} else {
|
54
|
+
state.loading = false;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
58
|
+
}, [fontSize, mockSize === null || mockSize === void 0 ? void 0 : mockSize.width, containerSize === null || containerSize === void 0 ? void 0 : containerSize.width]);
|
59
|
+
return state.loading ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
60
|
+
ref: refContainer,
|
61
|
+
flex: 1,
|
62
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, _objectSpread(_objectSpread({}, rest), {}, {
|
63
|
+
sx: sx,
|
64
|
+
noWrap: true,
|
65
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Skeleton, {
|
66
|
+
variant: "text",
|
67
|
+
sx: {
|
68
|
+
fontSize: '1rem'
|
69
|
+
}
|
70
|
+
})
|
71
|
+
})), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, _objectSpread(_objectSpread({
|
72
|
+
ref: refMock
|
73
|
+
}, rest), {}, {
|
74
|
+
sx: _objectSpread(_objectSpread({}, sx), {}, {
|
75
|
+
fontSize: "".concat(state.fontSize, "px !important"),
|
76
|
+
position: 'fixed',
|
77
|
+
top: -1000,
|
78
|
+
left: -1000
|
79
|
+
}),
|
80
|
+
noWrap: true,
|
81
|
+
children: children
|
82
|
+
}))]
|
83
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, _objectSpread(_objectSpread({}, rest), {}, {
|
84
|
+
sx: _objectSpread(_objectSpread({}, sx), {}, {
|
85
|
+
fontSize: "".concat(state.fontSize, "px !important")
|
86
|
+
}),
|
87
|
+
children: children
|
88
|
+
}));
|
89
|
+
}
|
90
|
+
Typography.propTypes = {
|
91
|
+
fontSize: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
|
92
|
+
children: _propTypes.default.any.isRequired,
|
93
|
+
minFontSize: _propTypes.default.number,
|
94
|
+
sx: _propTypes.default.object
|
95
|
+
};
|
96
|
+
Typography.defaultProps = {
|
97
|
+
fontSize: undefined,
|
98
|
+
minFontSize: 12,
|
99
|
+
sx: {}
|
100
|
+
};
|
@@ -0,0 +1,85 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.getAutoLoginFederated = getAutoLoginFederated;
|
7
|
+
exports.getConfig = getConfig;
|
8
|
+
exports.getCurrentApp = getCurrentApp;
|
9
|
+
exports.getFederatedApp = getFederatedApp;
|
10
|
+
exports.getMaster = getMaster;
|
11
|
+
exports.getSourceAppPid = getSourceAppPid;
|
12
|
+
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
14
|
+
function getMaster() {
|
15
|
+
var _blocklet$settings;
|
16
|
+
let blocklet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.blocklet;
|
17
|
+
const federated = (blocklet === null || blocklet === void 0 ? void 0 : (_blocklet$settings = blocklet.settings) === null || _blocklet$settings === void 0 ? void 0 : _blocklet$settings.federated) || {};
|
18
|
+
return federated.master;
|
19
|
+
}
|
20
|
+
function getConfig() {
|
21
|
+
var _blocklet$settings2;
|
22
|
+
let blocklet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.blocklet;
|
23
|
+
const federated = (blocklet === null || blocklet === void 0 ? void 0 : (_blocklet$settings2 = blocklet.settings) === null || _blocklet$settings2 === void 0 ? void 0 : _blocklet$settings2.federated) || {};
|
24
|
+
return federated.config;
|
25
|
+
}
|
26
|
+
function getAutoLoginFederated() {
|
27
|
+
let blocklet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.blocklet;
|
28
|
+
const config = getConfig(blocklet);
|
29
|
+
return Boolean(config === null || config === void 0 ? void 0 : config.autoLogin) && (config === null || config === void 0 ? void 0 : config.status) === 'approved';
|
30
|
+
}
|
31
|
+
function getSourceAppPid() {
|
32
|
+
let blocklet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.blocklet;
|
33
|
+
const master = getMaster(blocklet);
|
34
|
+
return master === null || master === void 0 ? void 0 : master.appPid;
|
35
|
+
}
|
36
|
+
function getFederatedApp() {
|
37
|
+
let blocklet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.blocklet;
|
38
|
+
const master = getMaster(blocklet);
|
39
|
+
const isFederatedMode = !(0, _isEmpty.default)(master);
|
40
|
+
return isFederatedMode ? {
|
41
|
+
appId: master.appId,
|
42
|
+
appName: master.appName,
|
43
|
+
appDescription: master.appDescription,
|
44
|
+
appLogo: master.appLogo,
|
45
|
+
appPid: master.appPid,
|
46
|
+
appUrl: master.appUrl,
|
47
|
+
version: master.version,
|
48
|
+
sourceAppPid: master.appPid,
|
49
|
+
provider: 'wallet'
|
50
|
+
} : null;
|
51
|
+
}
|
52
|
+
function getCurrentApp() {
|
53
|
+
let blocklet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.blocklet;
|
54
|
+
// 适用于 blocklet 项目
|
55
|
+
if (blocklet) {
|
56
|
+
return {
|
57
|
+
appId: blocklet.appId,
|
58
|
+
appName: blocklet.appName,
|
59
|
+
appDescription: blocklet.appDescription,
|
60
|
+
appLogo: blocklet.appLogo,
|
61
|
+
appPid: blocklet.appPid,
|
62
|
+
appUrl: blocklet.appUrl,
|
63
|
+
version: blocklet.version,
|
64
|
+
// NOTICE: null 代表该值置空
|
65
|
+
sourceAppPid: null,
|
66
|
+
provider: 'wallet'
|
67
|
+
};
|
68
|
+
}
|
69
|
+
// HACK: 适用于 blockelt-server
|
70
|
+
if (window.env) {
|
71
|
+
// eslint-disable-next-line no-param-reassign
|
72
|
+
blocklet = window.env;
|
73
|
+
return {
|
74
|
+
appId: blocklet.appId,
|
75
|
+
appName: blocklet.appName,
|
76
|
+
appDescription: blocklet.appDescription,
|
77
|
+
appUrl: blocklet.baseUrl,
|
78
|
+
// NOTICE: null 代表该值置空
|
79
|
+
sourceAppPid: null,
|
80
|
+
provider: 'wallet',
|
81
|
+
type: 'server'
|
82
|
+
};
|
83
|
+
}
|
84
|
+
return null;
|
85
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.7.
|
3
|
+
"version": "2.7.17",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -277,6 +277,10 @@
|
|
277
277
|
"import": "./es/Toast/index.js",
|
278
278
|
"require": "./lib/Toast/index.js"
|
279
279
|
},
|
280
|
+
"./lib/Typography": {
|
281
|
+
"import": "./es/Typography/index.js",
|
282
|
+
"require": "./lib/Typography/index.js"
|
283
|
+
},
|
280
284
|
"./lib/Util": {
|
281
285
|
"import": "./es/Util/index.js",
|
282
286
|
"require": "./lib/Util/index.js"
|
@@ -318,11 +322,11 @@
|
|
318
322
|
"peerDependencies": {
|
319
323
|
"react": ">=18.1.0"
|
320
324
|
},
|
321
|
-
"gitHead": "
|
325
|
+
"gitHead": "3a169b96cef38680f727a9d0aa0dc4588eaf85fd",
|
322
326
|
"dependencies": {
|
323
327
|
"@arcblock/did-motif": "^1.1.13",
|
324
|
-
"@arcblock/icons": "^2.7.
|
325
|
-
"@arcblock/react-hooks": "^2.7.
|
328
|
+
"@arcblock/icons": "^2.7.17",
|
329
|
+
"@arcblock/react-hooks": "^2.7.17",
|
326
330
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
327
331
|
"@emotion/react": "^11.10.4",
|
328
332
|
"@emotion/styled": "^11.10.4",
|
@@ -54,7 +54,7 @@ export default function AccountItem({ account, active, onDelete, onChoose, local
|
|
54
54
|
},
|
55
55
|
}}
|
56
56
|
className="session-manager-menu-item">
|
57
|
-
<Avatar did={account.did} />
|
57
|
+
<Avatar did={account.did} size={42} />
|
58
58
|
<Box
|
59
59
|
sx={{
|
60
60
|
flex: 1,
|
@@ -65,16 +65,14 @@ export default function AccountItem({ account, active, onDelete, onChoose, local
|
|
65
65
|
},
|
66
66
|
}}>
|
67
67
|
<DID did={account.did} copyable={false} size={14} responsive={false} compact sx={{ lineHeight: 1 }} />
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
{account.sourceAppPid && (
|
69
|
+
<Typography variant="caption">
|
70
|
+
{t('from')}{' '}
|
71
71
|
<Link href={account.appUrl} target="_blank" underline="none">
|
72
72
|
{account.appName}
|
73
73
|
</Link>
|
74
|
-
|
75
|
-
|
76
|
-
)}
|
77
|
-
</Typography>
|
74
|
+
</Typography>
|
75
|
+
)}
|
78
76
|
</Box>
|
79
77
|
<Box className="account-item-actions">
|
80
78
|
{active ? (
|
@@ -2,11 +2,11 @@ import { Icon } from '@iconify/react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { Menu, MenuItem, Typography } from '@mui/material';
|
4
4
|
import AddIcon from '@iconify-icons/ion/ios-add-circle-outline';
|
5
|
-
import isEmpty from 'lodash/isEmpty';
|
6
5
|
import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
|
7
6
|
import { useRef } from 'react';
|
8
7
|
import { translate } from '../Locale/util';
|
9
8
|
import { translations } from './translation';
|
9
|
+
import { getCurrentApp, getFederatedApp } from '../Util/federated';
|
10
10
|
|
11
11
|
export default function AddAccountItem({ onAdd, locale }) {
|
12
12
|
const addRef = useRef(null);
|
@@ -23,36 +23,18 @@ export default function AddAccountItem({ onAdd, locale }) {
|
|
23
23
|
return appList;
|
24
24
|
}
|
25
25
|
const blocklet = window?.blocklet;
|
26
|
-
|
27
|
-
|
26
|
+
|
27
|
+
const masterApp = getFederatedApp(blocklet);
|
28
|
+
const currentApp = getCurrentApp(blocklet);
|
29
|
+
|
30
|
+
if (currentApp) {
|
31
|
+
appList.push(currentApp);
|
28
32
|
}
|
29
|
-
|
30
|
-
|
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];
|
33
|
+
if (masterApp && masterApp?.appId !== currentApp?.appId) {
|
34
|
+
appList.push(masterApp);
|
54
35
|
}
|
55
|
-
|
36
|
+
// NOTICE: masterApp 应该排在前面
|
37
|
+
return appList.reverse();
|
56
38
|
}, [window.blocklet]);
|
57
39
|
|
58
40
|
const _onAdd = useMemoizedFn(() => {
|
@@ -96,7 +78,7 @@ export default function AddAccountItem({ onAdd, locale }) {
|
|
96
78
|
}}>
|
97
79
|
{apps.map((app) => (
|
98
80
|
<MenuItem key={app.appId} onClick={() => onAdd(app)}>
|
99
|
-
|
81
|
+
{t('connectWithAccount', { name: app.appName })}
|
100
82
|
</MenuItem>
|
101
83
|
))}
|
102
84
|
</Menu>
|
@@ -1,10 +1,11 @@
|
|
1
1
|
import PropTypes from 'prop-types';
|
2
|
-
import { useCallback
|
2
|
+
import { useCallback } 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
6
|
import ShieldCheckIcon from '@iconify-icons/mdi/shield-check';
|
7
7
|
import { Icon } from '@iconify/react';
|
8
|
+
import { useCreation, useReactive } from 'ahooks';
|
8
9
|
|
9
10
|
import UserPopper from './user-popper';
|
10
11
|
import DidAvatar from '../Avatar';
|
@@ -39,10 +40,13 @@ const translations = {
|
|
39
40
|
};
|
40
41
|
|
41
42
|
export default function FederatedLoginDetecter({ session, anchorEl, dark, locale: _locale }) {
|
42
|
-
const
|
43
|
+
const state = useReactive({
|
44
|
+
open: true,
|
45
|
+
});
|
43
46
|
|
44
|
-
const
|
45
|
-
|
47
|
+
const federatedMaster = useCreation(() => {
|
48
|
+
return session.federatedMaster;
|
49
|
+
}, [session?.federatedMaster]);
|
46
50
|
|
47
51
|
const localeList = Object.keys(translations);
|
48
52
|
const locale = localeList.includes(_locale) ? _locale : localeList[0];
|
@@ -53,19 +57,19 @@ export default function FederatedLoginDetecter({ session, anchorEl, dark, locale
|
|
53
57
|
if (err) {
|
54
58
|
Toast.error(err || translations[_locale].loginFederatedFailed);
|
55
59
|
} else {
|
56
|
-
|
60
|
+
state.open = false;
|
57
61
|
}
|
58
62
|
},
|
59
63
|
{
|
60
|
-
|
61
|
-
mode:
|
64
|
+
sourceAppPid: federatedMaster?.site?.appPid,
|
65
|
+
mode: federatedMaster?.user ? 'auto' : 'manual',
|
62
66
|
}
|
63
67
|
);
|
64
|
-
}, [session,
|
68
|
+
}, [session, federatedMaster?.site?.appPid, federatedMaster?.user, _locale, state]);
|
65
69
|
|
66
70
|
let appLogoUrl;
|
67
|
-
if (
|
68
|
-
appLogoUrl = new URL(
|
71
|
+
if (federatedMaster?.site) {
|
72
|
+
appLogoUrl = new URL(federatedMaster.site.appLogo, federatedMaster.site.appUrl);
|
69
73
|
appLogoUrl.searchParams.set('imageFilter', 'resize');
|
70
74
|
// HACK: 保持跟其他地方使用的尺寸一致,可以复用同一资源的缓存,减少网络请求
|
71
75
|
appLogoUrl.searchParams.set('w', '80');
|
@@ -73,26 +77,35 @@ export default function FederatedLoginDetecter({ session, anchorEl, dark, locale
|
|
73
77
|
}
|
74
78
|
|
75
79
|
return (
|
76
|
-
|
80
|
+
federatedMaster?.site && (
|
77
81
|
<UserPopper
|
78
|
-
open={
|
82
|
+
open={state.open}
|
79
83
|
anchorEl={anchorEl}
|
80
84
|
dark={dark}
|
81
85
|
autoClose={false}
|
82
|
-
onClose={() =>
|
86
|
+
onClose={() => {
|
87
|
+
state.open = false;
|
88
|
+
}}>
|
83
89
|
<Box p={2}>
|
84
|
-
{
|
90
|
+
{federatedMaster.site && (
|
85
91
|
<Box display="flex" alignItems="center">
|
86
|
-
<Box
|
92
|
+
<Box
|
93
|
+
component="img"
|
94
|
+
mr={2}
|
95
|
+
src={appLogoUrl.href}
|
96
|
+
alt={federatedMaster.site.appName}
|
97
|
+
width="30px"
|
98
|
+
height="30px"
|
99
|
+
/>
|
87
100
|
<Box sx={{ maxWidth: '260px' }}>
|
88
101
|
{translations[locale].useToConnect({
|
89
102
|
master: (
|
90
103
|
<Box
|
91
104
|
component="a"
|
92
|
-
href={
|
105
|
+
href={federatedMaster.site.appUrl}
|
93
106
|
target="_blank"
|
94
107
|
sx={{ textDecoration: 'none', fontWeight: 'bold', color: 'primary.main', fontSize: '1.2em' }}>
|
95
|
-
{
|
108
|
+
{federatedMaster.site.appName}
|
96
109
|
</Box>
|
97
110
|
),
|
98
111
|
member: window.blocklet.appName,
|
@@ -100,22 +113,22 @@ export default function FederatedLoginDetecter({ session, anchorEl, dark, locale
|
|
100
113
|
</Box>
|
101
114
|
</Box>
|
102
115
|
)}
|
103
|
-
{
|
104
|
-
{
|
116
|
+
{federatedMaster?.site && federatedMaster?.user && <Divider style={{ margin: '15px 0 10px 0' }} />}
|
117
|
+
{federatedMaster?.user && (
|
105
118
|
<Box display="flex" alignItems="center">
|
106
119
|
<DidAvatar
|
107
120
|
variant="circle"
|
108
|
-
did={
|
109
|
-
src={getUserAvatar(
|
121
|
+
did={federatedMaster.user.did}
|
122
|
+
src={getUserAvatar(federatedMaster.user.avatar)}
|
110
123
|
size={28}
|
111
124
|
shape="circle"
|
112
125
|
/>
|
113
126
|
<Box ml={2}>
|
114
127
|
<Box display="flex" justifyContent="space-between" alignItems="center">
|
115
|
-
<Box fontSize={18}>{
|
116
|
-
{
|
128
|
+
<Box fontSize={18}>{federatedMaster.user.fullName}</Box>
|
129
|
+
{federatedMaster.user.role?.toUpperCase() && (
|
117
130
|
<Chip
|
118
|
-
label={
|
131
|
+
label={federatedMaster.user.role?.toUpperCase()}
|
119
132
|
size="small"
|
120
133
|
variant="outlined"
|
121
134
|
sx={{ height: 'auto', marginRight: 0, fontSize: 12 }}
|
@@ -123,11 +136,11 @@ export default function FederatedLoginDetecter({ session, anchorEl, dark, locale
|
|
123
136
|
/>
|
124
137
|
)}
|
125
138
|
</Box>
|
126
|
-
<DidAddress responsive={false}>{
|
139
|
+
<DidAddress responsive={false}>{federatedMaster.user.did}</DidAddress>
|
127
140
|
</Box>
|
128
141
|
</Box>
|
129
142
|
)}
|
130
|
-
{
|
143
|
+
{federatedMaster?.site && (
|
131
144
|
<Box display="flex" justifyContent="center" mt={2}>
|
132
145
|
<Button variant="contained" size="small" onClick={onLoginFederated}>
|
133
146
|
{translations[locale].connect}
|
@@ -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,
|
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
|
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
|
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 } =
|
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
|
-
|
88
|
-
|
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 (
|
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
|
-
|
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
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
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', '
|
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;
|