@arcblock/ux 2.7.17 → 2.7.19

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.
@@ -2,13 +2,20 @@ import { Box, IconButton, Link, MenuItem, Typography } from '@mui/material';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Icon } from '@iconify/react';
4
4
  import CheckIcon from '@iconify-icons/mdi/check';
5
+ import AppleIOSIcon from '@iconify-icons/mdi/apple-ios';
6
+ import AndroidIcon from '@iconify-icons/mdi/android';
7
+ import WebIcon from '@iconify-icons/mdi/web';
8
+ import ApiIcon from '@iconify-icons/mdi/api';
9
+ import Auth0Icon from '@iconify-icons/logos/auth0-icon';
5
10
  import TrashCanOutlineIcon from '@iconify-icons/mdi/trash-can-outline';
6
- import { useMemoizedFn } from 'ahooks';
11
+ import { useCreation, useMemoizedFn } from 'ahooks';
7
12
  import Avatar from '../Avatar';
8
13
  import DID from '../DID';
9
14
  import { translate } from '../Locale/util';
10
15
  import { translations } from './translation';
16
+ import { getFederatedEnabled } from '../Util/federated';
11
17
  import { jsx as _jsx } from "react/jsx-runtime";
18
+ import { Fragment as _Fragment } from "react/jsx-runtime";
12
19
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
20
  export default function AccountItem({
14
21
  account,
@@ -20,6 +27,7 @@ export default function AccountItem({
20
27
  const t = useMemoizedFn((key, data = {}) => {
21
28
  return translate(translations, key, locale, 'en', data);
22
29
  });
30
+ const federatedEnabled = getFederatedEnabled();
23
31
  const _onChoose = useMemoizedFn(() => onChoose(account, {
24
32
  active
25
33
  }));
@@ -30,6 +38,64 @@ export default function AccountItem({
30
38
  active
31
39
  });
32
40
  });
41
+ const stopPropagation = useMemoizedFn(e => {
42
+ e.stopPropagation();
43
+ });
44
+ const walletIcon = useCreation(() => {
45
+ const {
46
+ walletOS,
47
+ provider
48
+ } = account;
49
+ if (provider === 'auth0') {
50
+ return /*#__PURE__*/_jsx(Icon, {
51
+ icon: Auth0Icon,
52
+ width: 10,
53
+ height: 10,
54
+ style: {
55
+ color: 'black'
56
+ }
57
+ });
58
+ }
59
+ if (walletOS === 'ios') {
60
+ return /*#__PURE__*/_jsx(Icon, {
61
+ icon: AppleIOSIcon,
62
+ width: 16,
63
+ height: 16,
64
+ style: {
65
+ color: 'black'
66
+ }
67
+ });
68
+ }
69
+ if (walletOS === 'android') {
70
+ return /*#__PURE__*/_jsx(Icon, {
71
+ icon: AndroidIcon,
72
+ width: 14,
73
+ height: 14,
74
+ style: {
75
+ color: 'black'
76
+ }
77
+ });
78
+ }
79
+ if (walletOS === 'web') {
80
+ return /*#__PURE__*/_jsx(Icon, {
81
+ icon: WebIcon,
82
+ style: {
83
+ color: 'black'
84
+ }
85
+ });
86
+ }
87
+ if (walletOS === 'api') {
88
+ return /*#__PURE__*/_jsx(Icon, {
89
+ icon: ApiIcon,
90
+ width: 14,
91
+ height: 14,
92
+ style: {
93
+ color: 'black'
94
+ }
95
+ });
96
+ }
97
+ return null;
98
+ }, [account.walletOS]);
33
99
  if (!account?.did || !account?.appName) {
34
100
  return null;
35
101
  }
@@ -80,14 +146,22 @@ export default function AccountItem({
80
146
  sx: {
81
147
  lineHeight: 1
82
148
  }
83
- }), account.sourceAppPid && /*#__PURE__*/_jsxs(Typography, {
149
+ }), /*#__PURE__*/_jsxs(Typography, {
84
150
  variant: "caption",
85
- children: [t('from'), ' ', /*#__PURE__*/_jsx(Link, {
86
- href: account.appUrl,
87
- target: "_blank",
88
- underline: "none",
89
- children: account.appName
90
- })]
151
+ display: "flex",
152
+ alignItems: "center",
153
+ gap: 0.5,
154
+ children: [walletIcon, federatedEnabled ? /*#__PURE__*/_jsxs(_Fragment, {
155
+ children: [t('from'), ' ', /*#__PURE__*/_jsx(Link, {
156
+ href: account.appUrl,
157
+ target: "_blank",
158
+ underline: "none",
159
+ onClick: stopPropagation,
160
+ children: account.appName
161
+ })]
162
+ }) :
163
+ // HACK: 用于在有 icon 的情况下,该该行的高度撑高为文字高度
164
+ walletIcon && ' ']
91
165
  })]
92
166
  }), /*#__PURE__*/_jsx(Box, {
93
167
  className: "account-item-actions",
@@ -6,7 +6,7 @@ import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
6
6
  import { useRef } from 'react';
7
7
  import { translate } from '../Locale/util';
8
8
  import { translations } from './translation';
9
- import { getCurrentApp, getFederatedApp } from '../Util/federated';
9
+ import { getApps } from '../Util/federated';
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
11
11
  import { jsxs as _jsxs } from "react/jsx-runtime";
12
12
  import { Fragment as _Fragment } from "react/jsx-runtime";
@@ -22,22 +22,8 @@ export default function AddAccountItem({
22
22
  return translate(translations, key, locale, 'en', data);
23
23
  });
24
24
  const apps = useCreation(() => {
25
- const appList = [];
26
- if (typeof window === 'undefined') {
27
- return appList;
28
- }
29
- const blocklet = window?.blocklet;
30
- const masterApp = getFederatedApp(blocklet);
31
- const currentApp = getCurrentApp(blocklet);
32
- if (currentApp) {
33
- appList.push(currentApp);
34
- }
35
- if (masterApp && masterApp?.appId !== currentApp?.appId) {
36
- appList.push(masterApp);
37
- }
38
- // NOTICE: masterApp 应该排在前面
39
- return appList.reverse();
40
- }, [window.blocklet]);
25
+ return getApps();
26
+ }, []);
41
27
  const _onAdd = useMemoizedFn(() => {
42
28
  if (apps.length <= 1) {
43
29
  onAdd(apps[0]);
@@ -83,8 +69,8 @@ export default function AddAccountItem({
83
69
  },
84
70
  children: apps.map(app => /*#__PURE__*/_jsx(MenuItem, {
85
71
  onClick: () => onAdd(app),
86
- children: t('connectWithAccount', {
87
- name: app.appName
72
+ children: t('addAppAccount', {
73
+ appName: app.appName
88
74
  })
89
75
  }, app.appId))
90
76
  }) : null]
@@ -93,10 +93,11 @@ function SessionManager({
93
93
  const targetApp = latestSession.current.user.sourceAppPid ? masterApp : currentApp;
94
94
  if (targetApp) {
95
95
  const loginAccount = {
96
+ ...targetApp,
96
97
  did: latestSession.current.user.did,
97
98
  avatar: latestSession.current.user.avatar,
98
- provider: latestSession.current.provider,
99
- ...targetApp
99
+ provider: latestSession.current.provider || targetApp.provider,
100
+ walletOS: latestSession.current.walletOS
100
101
  };
101
102
  connectAccount(loginAccount);
102
103
  }
@@ -53,13 +53,28 @@ export default function ManageAccounts({
53
53
  return;
54
54
  }
55
55
  close();
56
+ if (account.provider === 'auth0') {
57
+ // 如果切换的目标是 auth0,则直接打开 auth0 登录页面
58
+ session.switchDid((...args) => {
59
+ connectAccount();
60
+ onSwitchDid(...args);
61
+ }, {
62
+ allowWallet: false,
63
+ sourceAppPid: account.sourceAppPid
64
+ });
65
+ return;
66
+ }
67
+ const options = {
68
+ provider: account.provider,
69
+ sourceAppPid: account.sourceAppPid
70
+ };
71
+ if (account.did) {
72
+ options.forceConnected = account.did;
73
+ }
56
74
  session.switchDid((...args) => {
57
75
  connectAccount();
58
76
  onSwitchDid(...args);
59
- }, {
60
- provider: account.provider,
61
- sourceAppPid: account.sourceAppPid
62
- });
77
+ }, options);
63
78
  });
64
79
  const oauthConfigList = Object.entries(oauthConfigs).map(([key, value]) => {
65
80
  return {
@@ -103,7 +118,9 @@ export default function ManageAccounts({
103
118
  if (!isRawWalletAccount) {
104
119
  session.bindWallet(onBindWallet);
105
120
  } else {
106
- bindOAuth();
121
+ bindOAuth({
122
+ session
123
+ });
107
124
  }
108
125
  }
109
126
  return /*#__PURE__*/_jsxs(_Fragment, {
@@ -52,10 +52,9 @@ export default function MenuAccordion({
52
52
  },
53
53
  '.MuiAccordionDetails-root': {
54
54
  padding: 0,
55
- paddingLeft: '30px',
56
55
  '.session-manager-menu-item': {
57
56
  fontSize: '15px',
58
- padding: '12px 15px',
57
+ padding: '12px 15px 12px 42px',
59
58
  whiteSpace: 'normal'
60
59
  },
61
60
  '.session-manager-menu-icon': {
@@ -100,7 +100,6 @@ export default function UserInfo({
100
100
  children: [/*#__PURE__*/_jsx(Typography, {
101
101
  variant: "h5",
102
102
  fontWeight: "bold",
103
- fontSize: "auto",
104
103
  sx: {
105
104
  flex: 1,
106
105
  wordBreak: 'break-all'
@@ -1,6 +1,6 @@
1
1
  import PropTyps from 'prop-types';
2
2
  import { Box, Typography as MuiTypography, Skeleton } from '@mui/material';
3
- import { useReactive, useSize } from 'ahooks';
3
+ import { useCreation, useReactive, useSize } from 'ahooks';
4
4
  import { useEffect, useRef } from 'react';
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
6
6
  import { jsxs as _jsxs } from "react/jsx-runtime";
@@ -41,7 +41,13 @@ export default function Typography({
41
41
  }
42
42
  // eslint-disable-next-line react-hooks/exhaustive-deps
43
43
  }, [fontSize, mockSize?.width, containerSize?.width]);
44
- return state.loading ? /*#__PURE__*/_jsxs(Box, {
44
+ const loading = useCreation(() => {
45
+ if (fontSize === 'auto') {
46
+ return state.loading;
47
+ }
48
+ return false;
49
+ }, [fontSize, state.loading]);
50
+ return loading ? /*#__PURE__*/_jsxs(Box, {
45
51
  ref: refContainer,
46
52
  flex: 1,
47
53
  children: [/*#__PURE__*/_jsx(MuiTypography, {
@@ -11,6 +11,10 @@ export function getAutoLoginFederated(blocklet = window.blocklet) {
11
11
  const config = getConfig(blocklet);
12
12
  return Boolean(config?.autoLogin) && config?.status === 'approved';
13
13
  }
14
+ export function getFederatedEnabled(blocklet = window.blocklet) {
15
+ const config = getConfig(blocklet);
16
+ return config?.status === 'approved';
17
+ }
14
18
  export function getSourceAppPid(blocklet = window.blocklet) {
15
19
  const master = getMaster(blocklet);
16
20
  return master?.appPid;
@@ -62,4 +66,17 @@ export function getCurrentApp(blocklet = window.blocklet) {
62
66
  };
63
67
  }
64
68
  return null;
69
+ }
70
+ export function getApps(blocklet) {
71
+ const appList = [];
72
+ const masterApp = getFederatedApp(blocklet);
73
+ const currentApp = getCurrentApp(blocklet);
74
+ if (currentApp) {
75
+ appList.push(currentApp);
76
+ }
77
+ if (masterApp && masterApp?.appId !== currentApp?.appId) {
78
+ appList.push(masterApp);
79
+ }
80
+ // NOTICE: masterApp 应该排在前面
81
+ return appList.reverse();
65
82
  }
@@ -8,12 +8,18 @@ var _material = require("@mui/material");
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _react = require("@iconify/react");
10
10
  var _check = _interopRequireDefault(require("@iconify-icons/mdi/check"));
11
+ var _appleIos = _interopRequireDefault(require("@iconify-icons/mdi/apple-ios"));
12
+ var _android = _interopRequireDefault(require("@iconify-icons/mdi/android"));
13
+ var _web = _interopRequireDefault(require("@iconify-icons/mdi/web"));
14
+ var _api = _interopRequireDefault(require("@iconify-icons/mdi/api"));
15
+ var _auth0Icon = _interopRequireDefault(require("@iconify-icons/logos/auth0-icon"));
11
16
  var _trashCanOutline = _interopRequireDefault(require("@iconify-icons/mdi/trash-can-outline"));
12
17
  var _ahooks = require("ahooks");
13
18
  var _Avatar = _interopRequireDefault(require("../Avatar"));
14
19
  var _DID = _interopRequireDefault(require("../DID"));
15
20
  var _util = require("../Locale/util");
16
21
  var _translation = require("./translation");
22
+ var _federated = require("../Util/federated");
17
23
  var _jsxRuntime = require("react/jsx-runtime");
18
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
25
  function AccountItem(_ref) {
@@ -28,6 +34,7 @@ function AccountItem(_ref) {
28
34
  let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
29
35
  return (0, _util.translate)(_translation.translations, key, locale, 'en', data);
30
36
  });
37
+ const federatedEnabled = (0, _federated.getFederatedEnabled)();
31
38
  const _onChoose = (0, _ahooks.useMemoizedFn)(() => onChoose(account, {
32
39
  active
33
40
  }));
@@ -38,6 +45,64 @@ function AccountItem(_ref) {
38
45
  active
39
46
  });
40
47
  });
48
+ const stopPropagation = (0, _ahooks.useMemoizedFn)(e => {
49
+ e.stopPropagation();
50
+ });
51
+ const walletIcon = (0, _ahooks.useCreation)(() => {
52
+ const {
53
+ walletOS,
54
+ provider
55
+ } = account;
56
+ if (provider === 'auth0') {
57
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Icon, {
58
+ icon: _auth0Icon.default,
59
+ width: 10,
60
+ height: 10,
61
+ style: {
62
+ color: 'black'
63
+ }
64
+ });
65
+ }
66
+ if (walletOS === 'ios') {
67
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Icon, {
68
+ icon: _appleIos.default,
69
+ width: 16,
70
+ height: 16,
71
+ style: {
72
+ color: 'black'
73
+ }
74
+ });
75
+ }
76
+ if (walletOS === 'android') {
77
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Icon, {
78
+ icon: _android.default,
79
+ width: 14,
80
+ height: 14,
81
+ style: {
82
+ color: 'black'
83
+ }
84
+ });
85
+ }
86
+ if (walletOS === 'web') {
87
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Icon, {
88
+ icon: _web.default,
89
+ style: {
90
+ color: 'black'
91
+ }
92
+ });
93
+ }
94
+ if (walletOS === 'api') {
95
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Icon, {
96
+ icon: _api.default,
97
+ width: 14,
98
+ height: 14,
99
+ style: {
100
+ color: 'black'
101
+ }
102
+ });
103
+ }
104
+ return null;
105
+ }, [account.walletOS]);
41
106
  if (!(account !== null && account !== void 0 && account.did) || !(account !== null && account !== void 0 && account.appName)) {
42
107
  return null;
43
108
  }
@@ -88,14 +153,22 @@ function AccountItem(_ref) {
88
153
  sx: {
89
154
  lineHeight: 1
90
155
  }
91
- }), account.sourceAppPid && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Typography, {
156
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Typography, {
92
157
  variant: "caption",
93
- children: [t('from'), ' ', /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Link, {
94
- href: account.appUrl,
95
- target: "_blank",
96
- underline: "none",
97
- children: account.appName
98
- })]
158
+ display: "flex",
159
+ alignItems: "center",
160
+ gap: 0.5,
161
+ children: [walletIcon, federatedEnabled ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
162
+ children: [t('from'), ' ', /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Link, {
163
+ href: account.appUrl,
164
+ target: "_blank",
165
+ underline: "none",
166
+ onClick: stopPropagation,
167
+ children: account.appName
168
+ })]
169
+ }) :
170
+ // HACK: 用于在有 icon 的情况下,该该行的高度撑高为文字高度
171
+ walletIcon && ' ']
99
172
  })]
100
173
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
101
174
  className: "account-item-actions",
@@ -29,23 +29,8 @@ function AddAccountItem(_ref) {
29
29
  return (0, _util.translate)(_translation.translations, key, locale, 'en', data);
30
30
  });
31
31
  const apps = (0, _ahooks.useCreation)(() => {
32
- var _window;
33
- const appList = [];
34
- if (typeof window === 'undefined') {
35
- return appList;
36
- }
37
- const blocklet = (_window = window) === null || _window === void 0 ? void 0 : _window.blocklet;
38
- const masterApp = (0, _federated.getFederatedApp)(blocklet);
39
- const currentApp = (0, _federated.getCurrentApp)(blocklet);
40
- if (currentApp) {
41
- appList.push(currentApp);
42
- }
43
- if (masterApp && (masterApp === null || masterApp === void 0 ? void 0 : masterApp.appId) !== (currentApp === null || currentApp === void 0 ? void 0 : currentApp.appId)) {
44
- appList.push(masterApp);
45
- }
46
- // NOTICE: masterApp 应该排在前面
47
- return appList.reverse();
48
- }, [window.blocklet]);
32
+ return (0, _federated.getApps)();
33
+ }, []);
49
34
  const _onAdd = (0, _ahooks.useMemoizedFn)(() => {
50
35
  if (apps.length <= 1) {
51
36
  onAdd(apps[0]);
@@ -91,8 +76,8 @@ function AddAccountItem(_ref) {
91
76
  },
92
77
  children: apps.map(app => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, {
93
78
  onClick: () => onAdd(app),
94
- children: t('connectWithAccount', {
95
- name: app.appName
79
+ children: t('addAppAccount', {
80
+ appName: app.appName
96
81
  })
97
82
  }, app.appId))
98
83
  }) : null]
@@ -109,11 +109,12 @@ function SessionManager(_ref) {
109
109
  const masterApp = (0, _federated.getFederatedApp)(blocklet);
110
110
  const targetApp = latestSession.current.user.sourceAppPid ? masterApp : currentApp;
111
111
  if (targetApp) {
112
- const loginAccount = _objectSpread({
112
+ const loginAccount = _objectSpread(_objectSpread({}, targetApp), {}, {
113
113
  did: latestSession.current.user.did,
114
114
  avatar: latestSession.current.user.avatar,
115
- provider: latestSession.current.provider
116
- }, targetApp);
115
+ provider: latestSession.current.provider || targetApp.provider,
116
+ walletOS: latestSession.current.walletOS
117
+ });
117
118
  connectAccount(loginAccount);
118
119
  }
119
120
  });
@@ -64,13 +64,28 @@ function ManageAccounts(_ref) {
64
64
  return;
65
65
  }
66
66
  close();
67
+ if (account.provider === 'auth0') {
68
+ // 如果切换的目标是 auth0,则直接打开 auth0 登录页面
69
+ session.switchDid(function () {
70
+ connectAccount();
71
+ onSwitchDid(...arguments);
72
+ }, {
73
+ allowWallet: false,
74
+ sourceAppPid: account.sourceAppPid
75
+ });
76
+ return;
77
+ }
78
+ const options = {
79
+ provider: account.provider,
80
+ sourceAppPid: account.sourceAppPid
81
+ };
82
+ if (account.did) {
83
+ options.forceConnected = account.did;
84
+ }
67
85
  session.switchDid(function () {
68
86
  connectAccount();
69
87
  onSwitchDid(...arguments);
70
- }, {
71
- provider: account.provider,
72
- sourceAppPid: account.sourceAppPid
73
- });
88
+ }, options);
74
89
  });
75
90
  const oauthConfigList = Object.entries(oauthConfigs).map(_ref3 => {
76
91
  let [key, value] = _ref3;
@@ -115,7 +130,9 @@ function ManageAccounts(_ref) {
115
130
  if (!isRawWalletAccount) {
116
131
  session.bindWallet(onBindWallet);
117
132
  } else {
118
- bindOAuth();
133
+ bindOAuth({
134
+ session
135
+ });
119
136
  }
120
137
  }
121
138
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
@@ -60,10 +60,9 @@ function MenuAccordion(_ref) {
60
60
  },
61
61
  '.MuiAccordionDetails-root': {
62
62
  padding: 0,
63
- paddingLeft: '30px',
64
63
  '.session-manager-menu-item': {
65
64
  fontSize: '15px',
66
- padding: '12px 15px',
65
+ padding: '12px 15px 12px 42px',
67
66
  whiteSpace: 'normal'
68
67
  },
69
68
  '.session-manager-menu-icon': {
@@ -116,7 +116,6 @@ function UserInfo(_ref) {
116
116
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
117
117
  variant: "h5",
118
118
  fontWeight: "bold",
119
- fontSize: "auto",
120
119
  sx: {
121
120
  flex: 1,
122
121
  wordBreak: 'break-all'
@@ -56,7 +56,13 @@ function Typography(_ref) {
56
56
  }
57
57
  // eslint-disable-next-line react-hooks/exhaustive-deps
58
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, {
59
+ const loading = (0, _ahooks.useCreation)(() => {
60
+ if (fontSize === 'auto') {
61
+ return state.loading;
62
+ }
63
+ return false;
64
+ }, [fontSize, state.loading]);
65
+ return loading ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
60
66
  ref: refContainer,
61
67
  flex: 1,
62
68
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, _objectSpread(_objectSpread({}, rest), {}, {
@@ -3,10 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.getApps = getApps;
6
7
  exports.getAutoLoginFederated = getAutoLoginFederated;
7
8
  exports.getConfig = getConfig;
8
9
  exports.getCurrentApp = getCurrentApp;
9
10
  exports.getFederatedApp = getFederatedApp;
11
+ exports.getFederatedEnabled = getFederatedEnabled;
10
12
  exports.getMaster = getMaster;
11
13
  exports.getSourceAppPid = getSourceAppPid;
12
14
  var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
@@ -28,6 +30,11 @@ function getAutoLoginFederated() {
28
30
  const config = getConfig(blocklet);
29
31
  return Boolean(config === null || config === void 0 ? void 0 : config.autoLogin) && (config === null || config === void 0 ? void 0 : config.status) === 'approved';
30
32
  }
33
+ function getFederatedEnabled() {
34
+ let blocklet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.blocklet;
35
+ const config = getConfig(blocklet);
36
+ return (config === null || config === void 0 ? void 0 : config.status) === 'approved';
37
+ }
31
38
  function getSourceAppPid() {
32
39
  let blocklet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.blocklet;
33
40
  const master = getMaster(blocklet);
@@ -82,4 +89,17 @@ function getCurrentApp() {
82
89
  };
83
90
  }
84
91
  return null;
92
+ }
93
+ function getApps(blocklet) {
94
+ const appList = [];
95
+ const masterApp = getFederatedApp(blocklet);
96
+ const currentApp = getCurrentApp(blocklet);
97
+ if (currentApp) {
98
+ appList.push(currentApp);
99
+ }
100
+ if (masterApp && (masterApp === null || masterApp === void 0 ? void 0 : masterApp.appId) !== (currentApp === null || currentApp === void 0 ? void 0 : currentApp.appId)) {
101
+ appList.push(masterApp);
102
+ }
103
+ // NOTICE: masterApp 应该排在前面
104
+ return appList.reverse();
85
105
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.7.17",
3
+ "version": "2.7.19",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -322,21 +322,22 @@
322
322
  "peerDependencies": {
323
323
  "react": ">=18.1.0"
324
324
  },
325
- "gitHead": "3a169b96cef38680f727a9d0aa0dc4588eaf85fd",
325
+ "gitHead": "b87566fc7ec2502f2f1481189cd9a22a2ebde42e",
326
326
  "dependencies": {
327
327
  "@arcblock/did-motif": "^1.1.13",
328
- "@arcblock/icons": "^2.7.17",
329
- "@arcblock/react-hooks": "^2.7.17",
328
+ "@arcblock/icons": "^2.7.19",
329
+ "@arcblock/react-hooks": "^2.7.19",
330
330
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
331
331
  "@emotion/react": "^11.10.4",
332
332
  "@emotion/styled": "^11.10.4",
333
333
  "@fontsource/lato": "^4.5.10",
334
334
  "@fontsource/ubuntu-mono": "^4.5.11",
335
335
  "@iconify-icons/ion": "^1.2.10",
336
+ "@iconify-icons/logos": "^1.2.35",
336
337
  "@iconify-icons/mdi": "^1.2.47",
337
338
  "@iconify/react": "^4.1.1",
338
- "@mui/icons-material": "^5.10.6",
339
- "@mui/material": "^5.10.8",
339
+ "@mui/icons-material": "^5.14.8",
340
+ "@mui/material": "^5.14.8",
340
341
  "@solana/qr-code-styling": "^1.6.0-beta.0",
341
342
  "@testing-library/react": "^14.0.0",
342
343
  "ahooks": "^3.7.8",
@@ -352,7 +353,7 @@
352
353
  "is-svg": "^4.3.2",
353
354
  "js-cookie": "^2.2.1",
354
355
  "lodash": "^4.17.21",
355
- "mui-datatables": "^4.2.2",
356
+ "mui-datatables": "^4.3.0",
356
357
  "notistack": "^2.0.5",
357
358
  "pako": "^2.1.0",
358
359
  "react-cookie-consent": "^6.4.1",
@@ -2,19 +2,27 @@ import { Box, IconButton, Link, MenuItem, Typography } from '@mui/material';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Icon } from '@iconify/react';
4
4
  import CheckIcon from '@iconify-icons/mdi/check';
5
+ import AppleIOSIcon from '@iconify-icons/mdi/apple-ios';
6
+ import AndroidIcon from '@iconify-icons/mdi/android';
7
+ import WebIcon from '@iconify-icons/mdi/web';
8
+ import ApiIcon from '@iconify-icons/mdi/api';
9
+ import Auth0Icon from '@iconify-icons/logos/auth0-icon';
5
10
  import TrashCanOutlineIcon from '@iconify-icons/mdi/trash-can-outline';
6
- import { useMemoizedFn } from 'ahooks';
11
+ import { useCreation, useMemoizedFn } from 'ahooks';
7
12
 
8
13
  import Avatar from '../Avatar';
9
14
  import DID from '../DID';
10
15
  import { translate } from '../Locale/util';
11
16
  import { translations } from './translation';
17
+ import { getFederatedEnabled } from '../Util/federated';
12
18
 
13
19
  export default function AccountItem({ account, active, onDelete, onChoose, locale }) {
14
20
  const t = useMemoizedFn((key, data = {}) => {
15
21
  return translate(translations, key, locale, 'en', data);
16
22
  });
17
23
 
24
+ const federatedEnabled = getFederatedEnabled();
25
+
18
26
  const _onChoose = useMemoizedFn(() => onChoose(account, { active }));
19
27
 
20
28
  const _onDelete = useMemoizedFn((e) => {
@@ -23,6 +31,30 @@ export default function AccountItem({ account, active, onDelete, onChoose, local
23
31
  onDelete(account, { active });
24
32
  });
25
33
 
34
+ const stopPropagation = useMemoizedFn((e) => {
35
+ e.stopPropagation();
36
+ });
37
+
38
+ const walletIcon = useCreation(() => {
39
+ const { walletOS, provider } = account;
40
+ if (provider === 'auth0') {
41
+ return <Icon icon={Auth0Icon} width={10} height={10} style={{ color: 'black' }} />;
42
+ }
43
+ if (walletOS === 'ios') {
44
+ return <Icon icon={AppleIOSIcon} width={16} height={16} style={{ color: 'black' }} />;
45
+ }
46
+ if (walletOS === 'android') {
47
+ return <Icon icon={AndroidIcon} width={14} height={14} style={{ color: 'black' }} />;
48
+ }
49
+ if (walletOS === 'web') {
50
+ return <Icon icon={WebIcon} style={{ color: 'black' }} />;
51
+ }
52
+ if (walletOS === 'api') {
53
+ return <Icon icon={ApiIcon} width={14} height={14} style={{ color: 'black' }} />;
54
+ }
55
+ return null;
56
+ }, [account.walletOS]);
57
+
26
58
  if (!account?.did || !account?.appName) {
27
59
  return null;
28
60
  }
@@ -65,14 +97,20 @@ export default function AccountItem({ account, active, onDelete, onChoose, local
65
97
  },
66
98
  }}>
67
99
  <DID did={account.did} copyable={false} size={14} responsive={false} compact sx={{ lineHeight: 1 }} />
68
- {account.sourceAppPid && (
69
- <Typography variant="caption">
70
- {t('from')}{' '}
71
- <Link href={account.appUrl} target="_blank" underline="none">
72
- {account.appName}
73
- </Link>
74
- </Typography>
75
- )}
100
+ <Typography variant="caption" display="flex" alignItems="center" gap={0.5}>
101
+ {walletIcon}
102
+ {federatedEnabled ? (
103
+ <>
104
+ {t('from')}{' '}
105
+ <Link href={account.appUrl} target="_blank" underline="none" onClick={stopPropagation}>
106
+ {account.appName}
107
+ </Link>
108
+ </>
109
+ ) : (
110
+ // HACK: 用于在有 icon 的情况下,该该行的高度撑高为文字高度
111
+ walletIcon && ' '
112
+ )}
113
+ </Typography>
76
114
  </Box>
77
115
  <Box className="account-item-actions">
78
116
  {active ? (
@@ -6,7 +6,7 @@ import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
6
6
  import { useRef } from 'react';
7
7
  import { translate } from '../Locale/util';
8
8
  import { translations } from './translation';
9
- import { getCurrentApp, getFederatedApp } from '../Util/federated';
9
+ import { getApps } from '../Util/federated';
10
10
 
11
11
  export default function AddAccountItem({ onAdd, locale }) {
12
12
  const addRef = useRef(null);
@@ -18,24 +18,8 @@ export default function AddAccountItem({ onAdd, locale }) {
18
18
  return translate(translations, key, locale, 'en', data);
19
19
  });
20
20
  const apps = useCreation(() => {
21
- const appList = [];
22
- if (typeof window === 'undefined') {
23
- return appList;
24
- }
25
- const blocklet = window?.blocklet;
26
-
27
- const masterApp = getFederatedApp(blocklet);
28
- const currentApp = getCurrentApp(blocklet);
29
-
30
- if (currentApp) {
31
- appList.push(currentApp);
32
- }
33
- if (masterApp && masterApp?.appId !== currentApp?.appId) {
34
- appList.push(masterApp);
35
- }
36
- // NOTICE: masterApp 应该排在前面
37
- return appList.reverse();
38
- }, [window.blocklet]);
21
+ return getApps();
22
+ }, []);
39
23
 
40
24
  const _onAdd = useMemoizedFn(() => {
41
25
  if (apps.length <= 1) {
@@ -78,7 +62,7 @@ export default function AddAccountItem({ onAdd, locale }) {
78
62
  }}>
79
63
  {apps.map((app) => (
80
64
  <MenuItem key={app.appId} onClick={() => onAdd(app)}>
81
- {t('connectWithAccount', { name: app.appName })}
65
+ {t('addAppAccount', { appName: app.appName })}
82
66
  </MenuItem>
83
67
  ))}
84
68
  </Menu>
@@ -89,10 +89,11 @@ function SessionManager({
89
89
  const targetApp = latestSession.current.user.sourceAppPid ? masterApp : currentApp;
90
90
  if (targetApp) {
91
91
  const loginAccount = {
92
+ ...targetApp,
92
93
  did: latestSession.current.user.did,
93
94
  avatar: latestSession.current.user.avatar,
94
- provider: latestSession.current.provider,
95
- ...targetApp,
95
+ provider: latestSession.current.provider || targetApp.provider,
96
+ walletOS: latestSession.current.walletOS,
96
97
  };
97
98
  connectAccount(loginAccount);
98
99
  }
@@ -43,16 +43,31 @@ export default function ManageAccounts({
43
43
  return;
44
44
  }
45
45
  close();
46
- session.switchDid(
47
- (...args) => {
48
- connectAccount();
49
- onSwitchDid(...args);
50
- },
51
- {
52
- provider: account.provider,
53
- sourceAppPid: account.sourceAppPid,
54
- }
55
- );
46
+ if (account.provider === 'auth0') {
47
+ // 如果切换的目标是 auth0,则直接打开 auth0 登录页面
48
+ session.switchDid(
49
+ (...args) => {
50
+ connectAccount();
51
+ onSwitchDid(...args);
52
+ },
53
+ {
54
+ allowWallet: false,
55
+ sourceAppPid: account.sourceAppPid,
56
+ }
57
+ );
58
+ return;
59
+ }
60
+ const options = {
61
+ provider: account.provider,
62
+ sourceAppPid: account.sourceAppPid,
63
+ };
64
+ if (account.did) {
65
+ options.forceConnected = account.did;
66
+ }
67
+ session.switchDid((...args) => {
68
+ connectAccount();
69
+ onSwitchDid(...args);
70
+ }, options);
56
71
  });
57
72
 
58
73
  const oauthConfigList = Object.entries(oauthConfigs)
@@ -102,7 +117,7 @@ export default function ManageAccounts({
102
117
  if (!isRawWalletAccount) {
103
118
  session.bindWallet(onBindWallet);
104
119
  } else {
105
- bindOAuth();
120
+ bindOAuth({ session });
106
121
  }
107
122
  }
108
123
 
@@ -48,10 +48,9 @@ export default function MenuAccordion({ title, children, locale, expanded, onCha
48
48
  },
49
49
  '.MuiAccordionDetails-root': {
50
50
  padding: 0,
51
- paddingLeft: '30px',
52
51
  '.session-manager-menu-item': {
53
52
  fontSize: '15px',
54
- padding: '12px 15px',
53
+ padding: '12px 15px 12px 42px',
55
54
  whiteSpace: 'normal',
56
55
  },
57
56
  '.session-manager-menu-icon': {
@@ -80,7 +80,7 @@ export default function UserInfo({ session, locale, onSwitchProfile, onSwitchPas
80
80
  </Box>
81
81
  <Box sx={{ flex: 1, position: 'static', overflow: 'hidden', fontSize: '14px' }}>
82
82
  <Box display="flex" alignItems="center" gap="4px" mb={0.5}>
83
- <Typography variant="h5" fontWeight="bold" fontSize="auto" sx={{ flex: 1, wordBreak: 'break-all' }}>
83
+ <Typography variant="h5" fontWeight="bold" sx={{ flex: 1, wordBreak: 'break-all' }}>
84
84
  {session.user.fullName}
85
85
  </Typography>
86
86
  <Chip
@@ -1,6 +1,6 @@
1
1
  import PropTyps from 'prop-types';
2
2
  import { Box, Typography as MuiTypography, Skeleton } from '@mui/material';
3
- import { useReactive, useSize } from 'ahooks';
3
+ import { useCreation, useReactive, useSize } from 'ahooks';
4
4
  import { useEffect, useRef } from 'react';
5
5
 
6
6
  export default function Typography({ minFontSize, fontSize, children, sx, ...rest }) {
@@ -35,7 +35,14 @@ export default function Typography({ minFontSize, fontSize, children, sx, ...res
35
35
  // eslint-disable-next-line react-hooks/exhaustive-deps
36
36
  }, [fontSize, mockSize?.width, containerSize?.width]);
37
37
 
38
- return state.loading ? (
38
+ const loading = useCreation(() => {
39
+ if (fontSize === 'auto') {
40
+ return state.loading;
41
+ }
42
+ return false;
43
+ }, [fontSize, state.loading]);
44
+
45
+ return loading ? (
39
46
  <Box ref={refContainer} flex={1}>
40
47
  <MuiTypography {...rest} sx={sx} noWrap>
41
48
  <Skeleton variant="text" sx={{ fontSize: '1rem' }} />
@@ -15,6 +15,11 @@ export function getAutoLoginFederated(blocklet = window.blocklet) {
15
15
  return Boolean(config?.autoLogin) && config?.status === 'approved';
16
16
  }
17
17
 
18
+ export function getFederatedEnabled(blocklet = window.blocklet) {
19
+ const config = getConfig(blocklet);
20
+ return config?.status === 'approved';
21
+ }
22
+
18
23
  export function getSourceAppPid(blocklet = window.blocklet) {
19
24
  const master = getMaster(blocklet);
20
25
  return master?.appPid;
@@ -71,3 +76,19 @@ export function getCurrentApp(blocklet = window.blocklet) {
71
76
  }
72
77
  return null;
73
78
  }
79
+
80
+ export function getApps(blocklet) {
81
+ const appList = [];
82
+
83
+ const masterApp = getFederatedApp(blocklet);
84
+ const currentApp = getCurrentApp(blocklet);
85
+
86
+ if (currentApp) {
87
+ appList.push(currentApp);
88
+ }
89
+ if (masterApp && masterApp?.appId !== currentApp?.appId) {
90
+ appList.push(masterApp);
91
+ }
92
+ // NOTICE: masterApp 应该排在前面
93
+ return appList.reverse();
94
+ }