@arcblock/ux 2.8.26 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/es/Address/did-address.js +33 -21
  2. package/es/AnimationWaiter/index.js +2 -1
  3. package/es/Avatar/index.js +1 -1
  4. package/es/BlockletContext/index.js +1 -1
  5. package/es/CardSelector/index.js +2 -1
  6. package/es/Colors/index.js +2 -1
  7. package/es/Colors/themes/temp.js +17 -0
  8. package/es/Datatable/TableSearch.js +2 -1
  9. package/es/Img/index.js +7 -6
  10. package/es/Locale/selector.js +15 -13
  11. package/es/NFTDisplay/index.js +2 -1
  12. package/es/QRCode/index.js +2 -1
  13. package/es/SessionBlocklet/index.js +169 -0
  14. package/es/SessionManager/index.js +2 -381
  15. package/es/SessionPermission/index.js +28 -0
  16. package/es/SessionUser/components/logged-in.js +224 -0
  17. package/es/SessionUser/components/session-user-item.js +148 -0
  18. package/es/SessionUser/components/session-user-switch.js +213 -0
  19. package/es/SessionUser/components/un-login.js +64 -0
  20. package/es/SessionUser/components/user-info.js +163 -0
  21. package/es/SessionUser/index.js +49 -0
  22. package/es/SessionUser/libs/translation.js +19 -0
  23. package/es/SessionUser/libs/utils.js +4 -0
  24. package/es/SplitButton/index.js +2 -1
  25. package/es/Toast/index.js +1 -1
  26. package/es/Util/constant.js +10 -0
  27. package/es/Util/index.js +11 -0
  28. package/lib/Address/did-address.js +36 -22
  29. package/lib/AnimationWaiter/index.js +2 -1
  30. package/lib/Avatar/index.js +1 -1
  31. package/lib/BlockletContext/index.js +1 -1
  32. package/lib/CardSelector/index.js +2 -1
  33. package/lib/Colors/index.js +7 -0
  34. package/lib/Colors/themes/temp.js +24 -0
  35. package/lib/Datatable/TableSearch.js +2 -1
  36. package/lib/Img/index.js +7 -6
  37. package/lib/Locale/selector.js +14 -13
  38. package/lib/NFTDisplay/index.js +2 -1
  39. package/lib/QRCode/index.js +2 -1
  40. package/lib/SessionBlocklet/index.js +187 -0
  41. package/lib/SessionManager/index.js +2 -390
  42. package/lib/SessionPermission/index.js +38 -0
  43. package/lib/SessionUser/components/logged-in.js +243 -0
  44. package/lib/SessionUser/components/session-user-item.js +163 -0
  45. package/lib/SessionUser/components/session-user-switch.js +232 -0
  46. package/lib/SessionUser/components/un-login.js +72 -0
  47. package/lib/SessionUser/components/user-info.js +175 -0
  48. package/lib/SessionUser/index.js +57 -0
  49. package/lib/SessionUser/libs/translation.js +26 -0
  50. package/lib/{SessionManager → SessionUser}/libs/utils.js +8 -1
  51. package/lib/SplitButton/index.js +2 -1
  52. package/lib/Toast/index.js +5 -5
  53. package/lib/Util/constant.js +26 -0
  54. package/lib/Util/index.js +16 -3
  55. package/package.json +19 -7
  56. package/src/Address/did-address.jsx +34 -20
  57. package/src/AnimationWaiter/index.js +2 -1
  58. package/src/Avatar/index.jsx +1 -1
  59. package/src/BlockletContext/index.jsx +1 -1
  60. package/src/CardSelector/index.jsx +2 -1
  61. package/src/Colors/index.js +1 -0
  62. package/src/Colors/themes/temp.js +18 -0
  63. package/src/Datatable/TableSearch.js +3 -1
  64. package/src/Img/{index.js → index.jsx} +8 -6
  65. package/src/Locale/selector.jsx +11 -8
  66. package/src/NFTDisplay/index.js +2 -1
  67. package/src/QRCode/index.js +2 -1
  68. package/src/SessionBlocklet/index.jsx +181 -0
  69. package/src/SessionManager/index.jsx +2 -369
  70. package/src/SessionPermission/index.jsx +28 -0
  71. package/src/SessionUser/components/logged-in.jsx +194 -0
  72. package/src/SessionUser/components/session-user-item.jsx +96 -0
  73. package/src/SessionUser/components/session-user-switch.jsx +222 -0
  74. package/src/SessionUser/components/un-login.jsx +55 -0
  75. package/src/SessionUser/components/user-info.jsx +165 -0
  76. package/src/SessionUser/index.jsx +38 -0
  77. package/src/SessionUser/libs/translation.js +19 -0
  78. package/src/{SessionManager → SessionUser}/libs/utils.js +4 -0
  79. package/src/SplitButton/index.js +2 -1
  80. package/src/Toast/index.js +1 -1
  81. package/src/Util/constant.js +12 -0
  82. package/src/Util/index.js +13 -0
  83. package/es/SessionManager/components/account-item.js +0 -212
  84. package/es/SessionManager/components/add-account-item.js +0 -57
  85. package/es/SessionManager/components/federated-login-detecter.js +0 -183
  86. package/es/SessionManager/components/manage-accounts.js +0 -219
  87. package/es/SessionManager/components/manage-blocklet.js +0 -70
  88. package/es/SessionManager/components/menu-accordion.js +0 -103
  89. package/es/SessionManager/components/responsive-popper.js +0 -24
  90. package/es/SessionManager/components/user-drawer.js +0 -68
  91. package/es/SessionManager/components/user-info.js +0 -143
  92. package/es/SessionManager/components/user-popper.js +0 -110
  93. package/es/SessionManager/hooks/use-config.js +0 -34
  94. package/es/SessionManager/libs/translation.js +0 -52
  95. package/es/SessionManager/libs/utils.js +0 -2
  96. package/lib/SessionManager/components/account-item.js +0 -219
  97. package/lib/SessionManager/components/add-account-item.js +0 -66
  98. package/lib/SessionManager/components/federated-login-detecter.js +0 -193
  99. package/lib/SessionManager/components/manage-accounts.js +0 -232
  100. package/lib/SessionManager/components/manage-blocklet.js +0 -86
  101. package/lib/SessionManager/components/menu-accordion.js +0 -111
  102. package/lib/SessionManager/components/responsive-popper.js +0 -34
  103. package/lib/SessionManager/components/user-drawer.js +0 -75
  104. package/lib/SessionManager/components/user-info.js +0 -160
  105. package/lib/SessionManager/components/user-popper.js +0 -104
  106. package/lib/SessionManager/hooks/use-config.js +0 -41
  107. package/lib/SessionManager/libs/translation.js +0 -59
  108. package/src/SessionManager/components/account-item.jsx +0 -156
  109. package/src/SessionManager/components/add-account-item.jsx +0 -49
  110. package/src/SessionManager/components/federated-login-detecter.jsx +0 -167
  111. package/src/SessionManager/components/manage-accounts.jsx +0 -228
  112. package/src/SessionManager/components/manage-blocklet.jsx +0 -70
  113. package/src/SessionManager/components/menu-accordion.jsx +0 -93
  114. package/src/SessionManager/components/responsive-popper.jsx +0 -26
  115. package/src/SessionManager/components/user-drawer.jsx +0 -57
  116. package/src/SessionManager/components/user-info.jsx +0 -117
  117. package/src/SessionManager/components/user-popper.jsx +0 -95
  118. package/src/SessionManager/hooks/use-config.js +0 -33
  119. package/src/SessionManager/libs/translation.js +0 -52
@@ -0,0 +1,181 @@
1
+ import { useRef } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ Box,
5
+ ClickAwayListener,
6
+ Fade,
7
+ IconButton,
8
+ List,
9
+ ListItem,
10
+ ListItemButton,
11
+ Paper,
12
+ Popper,
13
+ Typography,
14
+ } from '@mui/material';
15
+ import { Icon } from '@iconify/react';
16
+ import DashboardOutlineRoundedIcon from '@iconify-icons/material-symbols/dashboard-outline-rounded';
17
+ import WidgetsOutlineRoundedIcon from '@iconify-icons/material-symbols/widgets-outline-rounded';
18
+ import { useMemoizedFn, useReactive } from 'ahooks';
19
+
20
+ import Button from '../Button';
21
+ import { temp as colors } from '../Colors';
22
+ import { AUTH_SERVICE_PREFIX, NAVIGATION_URL } from '../Util/constant';
23
+ import SessionPermission from '../SessionPermission';
24
+
25
+ export default function SessionBlocklet({ session, locale, size }) {
26
+ const blocklet = window?.blocklet || {};
27
+ const sessionMenuList = (blocklet.navigation || [])
28
+ // HACK 过滤掉默认插入的 /sessionManager 菜单
29
+ .filter((item) => item.section === 'sessionManager' && !['/sessionManager'].includes(item.id))
30
+ .filter((item) => {
31
+ if ((item?.role || []).includes(session?.user?.role || 'guest')) {
32
+ return true;
33
+ }
34
+ return false;
35
+ })
36
+ .map((item) => {
37
+ const component = (blocklet?.componentMountPoints || []).find((x) => item.component === x.name);
38
+ return {
39
+ ...item,
40
+ component,
41
+ };
42
+ });
43
+ const popperAnchorRef = useRef(null);
44
+ const currentState = useReactive({
45
+ open: false,
46
+ });
47
+ const onTogglePopper = useMemoizedFn((value = !currentState.open) => {
48
+ currentState.open = value;
49
+ });
50
+
51
+ if (sessionMenuList.length === 0) {
52
+ return null;
53
+ }
54
+
55
+ return (
56
+ <>
57
+ <IconButton size="medium" ref={popperAnchorRef} onClick={() => onTogglePopper()}>
58
+ <Icon icon={DashboardOutlineRoundedIcon} fontSize={size} />
59
+ </IconButton>
60
+ <Popper
61
+ open={currentState.open}
62
+ onClose={() => onTogglePopper(false)}
63
+ anchorEl={popperAnchorRef.current}
64
+ transition
65
+ placement="bottom-end"
66
+ sx={{ zIndex: 1600 }}>
67
+ {({ TransitionProps }) => (
68
+ <ClickAwayListener
69
+ onClickAway={(e) => {
70
+ e.preventDefault();
71
+ e.stopPropagation();
72
+ onTogglePopper(false);
73
+ }}>
74
+ <Fade {...TransitionProps} timeout={350}>
75
+ <Paper
76
+ variant="outlined"
77
+ sx={{
78
+ borderRadius: 3,
79
+ width: 350,
80
+ maxWidth: '90vw',
81
+ borderColor: colors.lineStep,
82
+ p: 2,
83
+ border: '0 !important',
84
+ boxShadow: `0px 8px 16px 0px ${colors.gray6}, 0px 0px 0px 1px ${colors.gray6}`,
85
+ }}>
86
+ <List
87
+ sx={{
88
+ display: 'grid',
89
+ gridTemplateColumns: 'repeat(auto-fill, 100px)',
90
+ gridAutoRows: 'minmax(100px, max-content)',
91
+ justifyContent: 'space-between',
92
+ maxHeight: 350,
93
+ overflowY: 'auto',
94
+ p: 0,
95
+ }}>
96
+ {sessionMenuList.map((item) => (
97
+ <ListItem key={item.id} disablePadding>
98
+ <ListItemButton
99
+ href={item.link}
100
+ sx={{
101
+ p: 1,
102
+ display: 'flex',
103
+ flexDirection: 'column',
104
+ alignItems: 'center',
105
+ gap: 1,
106
+ width: '100%',
107
+ height: '100%',
108
+ borderRadius: 2,
109
+ '&:hover': {
110
+ backgroundColor: colors.surfacePrimarySubtitle,
111
+ },
112
+ }}>
113
+ {item?.component?.did ? (
114
+ <Box
115
+ component="img"
116
+ src={`${AUTH_SERVICE_PREFIX}/blocklet/logo-bundle/${item.component.did}`}
117
+ sx={{
118
+ borderRadius: 2,
119
+ width: 50,
120
+ height: 50,
121
+ objectFit: 'contain',
122
+ }}
123
+ />
124
+ ) : (
125
+ <Icon
126
+ fontSize={50}
127
+ icon={item.icon || WidgetsOutlineRoundedIcon}
128
+ color={colors.textSubtitle}
129
+ />
130
+ )}
131
+
132
+ <Typography
133
+ sx={{
134
+ fontSize: '12px',
135
+ color: colors.textBase,
136
+ textAlign: 'center',
137
+ lineHeight: 'normal',
138
+ }}>
139
+ {item.title?.zh || item.title}
140
+ </Typography>
141
+ </ListItemButton>
142
+ </ListItem>
143
+ ))}
144
+ </List>
145
+ <SessionPermission session={session}>
146
+ <Button
147
+ variant="outlined"
148
+ fullWidth
149
+ href={NAVIGATION_URL}
150
+ sx={{
151
+ mt: 1,
152
+ borderRadius: 2,
153
+ color: colors.textBase,
154
+ borderColor: colors.lineBorderStrong,
155
+ '&:hover': {
156
+ color: colors.primaryBase,
157
+ borderColor: colors.primaryBase,
158
+ },
159
+ }}>
160
+ {locale === 'zh' ? '管理' : 'Manage'}
161
+ </Button>
162
+ </SessionPermission>
163
+ </Paper>
164
+ </Fade>
165
+ </ClickAwayListener>
166
+ )}
167
+ </Popper>
168
+ </>
169
+ );
170
+ }
171
+
172
+ SessionBlocklet.propTypes = {
173
+ session: PropTypes.object.isRequired,
174
+ locale: PropTypes.string,
175
+ size: PropTypes.number,
176
+ };
177
+
178
+ SessionBlocklet.defaultProps = {
179
+ locale: 'en',
180
+ size: 24,
181
+ };
@@ -1,370 +1,3 @@
1
- /* eslint-disable react/prop-types */
2
- /* eslint-disable react/jsx-no-bind */
3
- import { useEffect, useMemo, useRef, useState } from 'react';
4
- import PropTypes from 'prop-types';
5
- import { Box, IconButton, MenuList, Button, CircularProgress, Divider } from '@mui/material';
6
- import AccountIcon from '@arcblock/icons/lib/Account';
7
- import noop from 'lodash/noop';
8
- import cloneDeep from 'lodash/cloneDeep';
9
- import { useLatest, useMemoizedFn } from 'ahooks';
1
+ import SessionUser from '../SessionUser';
10
2
 
11
- import DidAvatar from '../Avatar';
12
- import { getUserAvatar, sleep } from '../Util';
13
- import FederatedLoginDetecter from './components/federated-login-detecter';
14
- import UserInfo from './components/user-info';
15
- import ResponsivePopper from './components/responsive-popper';
16
- import { translate } from '../Locale/util';
17
- import ManageAccounts from './components/manage-accounts';
18
- import ManageBlocklet from './components/manage-blocklet';
19
- import { translations } from './libs/translation';
20
- import { getConnectedAccounts, getSourceProvider } from './libs/utils';
21
- import useConfig from './hooks/use-config';
22
- import { getCurrentApp, getFederatedApp } from '../Util/federated';
23
-
24
- function SessionManager({
25
- session,
26
- locale,
27
- showText,
28
- showRole,
29
- switchDid,
30
- switchProfile,
31
- switchPassport,
32
- disableLogout,
33
- onLogin,
34
- onLogout,
35
- onSwitchDid,
36
- onSwitchProfile,
37
- onSwitchPassport,
38
- onBindWallet,
39
- menu,
40
- menuRender,
41
- dark,
42
- size,
43
- showManageBlocklet,
44
- ...rest
45
- }) {
46
- const latestSession = useLatest(session);
47
- const { connectAccount, config, setConfig, deleteAccount } = useConfig();
48
- const t = useMemoizedFn((key, data = {}) => {
49
- return translate(translations, key, locale, 'en', data);
50
- });
51
- const userAnchorRef = useRef(null);
52
- const { logoutOAuth, switchOAuthPassport } = session.useOAuth();
53
- const [userOpen, setUserOpen] = useState(false);
54
-
55
- // base64 img maybe have some blank char, need encodeURIComponent to transform it
56
- const avatar = getUserAvatar(session.user?.avatar?.replace(/\s/g, encodeURIComponent(' ')));
57
-
58
- const isRawWalletAccount = getSourceProvider(session.user) === 'wallet';
59
- const connectedAccounts = getConnectedAccounts(session.user);
60
-
61
- const isFirstLoading = useMemo(() => {
62
- return session?.initialized === false && session?.loading === true;
63
- }, [session?.initialized, session?.loading]);
64
-
65
- let hasBindWallet = false;
66
- let hasBindAccount = false;
67
- if (isRawWalletAccount) {
68
- if (connectedAccounts.some((item) => item.provider !== 'wallet')) {
69
- hasBindAccount = true;
70
- }
71
- hasBindWallet = true;
72
- } else if (connectedAccounts.some((item) => item.provider === 'wallet')) {
73
- hasBindAccount = true;
74
- hasBindWallet = true;
75
- }
76
-
77
- const _connectAccount = useMemoizedFn(async () => {
78
- // HACK: 强制等待组件渲染一轮,以拿到最新的 session 值
79
- await sleep();
80
- if (!latestSession.current?.user) {
81
- return;
82
- }
83
- if (typeof window === 'undefined') {
84
- return;
85
- }
86
- const blocklet = window?.blocklet;
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
- ...targetApp,
93
- did: latestSession.current.user.did,
94
- avatar: latestSession.current.user.avatar,
95
- provider: latestSession.current.provider || targetApp.provider,
96
- walletOS: latestSession.current.walletOS,
97
- };
98
- connectAccount(loginAccount);
99
- }
100
- });
101
-
102
- // HACK: 用于处理 统一登录 的自动登录情况,添加一个已连接的账号
103
- // 同时可用于以前的站点,会自动生成一个已连接的账号
104
- useEffect(() => {
105
- if (session.user) {
106
- _connectAccount();
107
- }
108
- // eslint-disable-next-line react-hooks/exhaustive-deps
109
- }, [session.user]);
110
-
111
- if (!session.user) {
112
- return (
113
- <>
114
- {showText ? (
115
- <Button
116
- ref={userAnchorRef}
117
- sx={[{ borderRadius: '100vw' }, dark && { color: '#fff', borderColor: '#fff' }]}
118
- variant="outlined"
119
- onClick={_onLogin}
120
- role="button"
121
- aria-label="Login button"
122
- {...rest}
123
- data-cy="sessionManager-login">
124
- {isFirstLoading ? <CircularProgress /> : <AccountIcon />}
125
- <span style={{ lineHeight: '25px' }}>{t('connect')}</span>
126
- </Button>
127
- ) : (
128
- <IconButton
129
- ref={userAnchorRef}
130
- {...rest}
131
- onClick={_onLogin}
132
- data-cy="sessionManager-login"
133
- size="medium"
134
- role="button"
135
- aria-label="Login button">
136
- {isFirstLoading ? (
137
- <Box width={size} height={size} display="flex" justifyContent="center" alignItems="center">
138
- <CircularProgress style={{ width: size - 4, height: size - 4, color: dark ? '#fff' : '' }} />
139
- </Box>
140
- ) : (
141
- <AccountIcon style={{ width: size, height: size, color: dark ? '#fff' : '' }} />
142
- )}
143
- </IconButton>
144
- )}
145
-
146
- <FederatedLoginDetecter locale={locale} dark={dark} session={session} anchorEl={userAnchorRef.current} />
147
- </>
148
- );
149
- }
150
-
151
- function onToggleUser() {
152
- setUserOpen((prevOpen) => !prevOpen);
153
- }
154
-
155
- function close() {
156
- setUserOpen(false);
157
- }
158
-
159
- function onCloseUser(e) {
160
- if (userAnchorRef.current && userAnchorRef.current.contains(e.target)) {
161
- return;
162
- }
163
- close();
164
- }
165
-
166
- function _onLogin() {
167
- if (!isFirstLoading) {
168
- session.login((...args) => {
169
- _connectAccount();
170
- onLogin(...args);
171
- });
172
- }
173
- }
174
- function _onLogout() {
175
- return new Promise((resolve, reject) => {
176
- logoutOAuth({ session, hack: true })
177
- .catch((err) => {
178
- console.error(err);
179
- reject(err);
180
- })
181
- .finally(() => {
182
- session.logout((...args) => {
183
- onLogout(...args);
184
- resolve();
185
- close();
186
- });
187
- });
188
- });
189
- }
190
- /**
191
- * @name 切换账户
192
- * @description 该功能仅在登录后才能使用,目前仅用于切换普通登录和统一登录的账户,所以会增加一些与统一登录相关的逻辑
193
- */
194
-
195
- function _onSwitchProfile() {
196
- session.switchProfile((...args) => {
197
- close();
198
- onSwitchProfile(...args);
199
- });
200
- }
201
-
202
- function _onSwitchPassport() {
203
- const { user, provider } = session;
204
- if (['auth0'].includes(provider)) {
205
- switchOAuthPassport(user);
206
- } else {
207
- close();
208
- session.switchPassport((...args) => {
209
- close();
210
- onSwitchPassport(...args);
211
- });
212
- }
213
- }
214
-
215
- return (
216
- <>
217
- <IconButton
218
- ref={userAnchorRef}
219
- onClick={onToggleUser}
220
- {...rest}
221
- data-cy="sessionManager-logout-popup"
222
- size="medium"
223
- role="button"
224
- aria-label="User info button"
225
- style={{ lineHeight: 1 }}>
226
- <DidAvatar variant="circle" did={session.user.did} src={avatar} size={size} shape="circle" />
227
- </IconButton>
228
-
229
- <ResponsivePopper open={userOpen} onClose={onCloseUser} anchorEl={userAnchorRef.current} dark={dark}>
230
- <MenuList sx={{ p: 0 }}>
231
- <UserInfo
232
- session={session}
233
- size={size}
234
- locale={locale}
235
- onSwitchProfile={() => {
236
- close();
237
- _onSwitchProfile();
238
- }}
239
- onSwitchPassport={() => {
240
- close();
241
- _onSwitchPassport();
242
- }}
243
- close={close}
244
- switchProfile={switchProfile}
245
- hasBindWallet={hasBindWallet}
246
- />
247
-
248
- <Divider />
249
-
250
- <ManageAccounts
251
- session={session}
252
- locale={locale}
253
- onBindWallet={onBindWallet}
254
- onSwitchDid={onSwitchDid}
255
- connectAccount={_connectAccount}
256
- close={close}
257
- hasBindAccount={hasBindAccount}
258
- onLogout={_onLogout}
259
- expanded={config.expandAccount}
260
- onExpand={(value) => {
261
- const cloneConfig = cloneDeep(config);
262
- cloneConfig.expandAccount = value;
263
- setConfig(cloneConfig);
264
- }}
265
- deleteAccount={deleteAccount}
266
- accounts={config.accounts}
267
- />
268
-
269
- {/* 为了避免控制台出现警告,采用数组的方式 */}
270
- {/* MUI:The Menu component doesn't accept a Fragment as a child. Consider providing an array instead. */}
271
- {showManageBlocklet
272
- ? [
273
- <Divider key="divider" />,
274
- <ManageBlocklet
275
- key="manageBlocklet"
276
- menu={menu}
277
- menuRender={menuRender}
278
- locale={locale}
279
- expanded={config.expandBlocklet}
280
- onExpand={(value) => {
281
- const cloneConfig = cloneDeep(config);
282
- cloneConfig.expandBlocklet = value;
283
- setConfig(cloneConfig);
284
- }}
285
- />,
286
- ]
287
- : null}
288
- </MenuList>
289
- </ResponsivePopper>
290
- </>
291
- );
292
- }
293
-
294
- SessionManager.propTypes = {
295
- session: PropTypes.shape({
296
- federatedMaster: PropTypes.object,
297
- provider: PropTypes.oneOf(['wallet', 'auth0', '']),
298
- user: PropTypes.shape({
299
- did: PropTypes.string.isRequired,
300
- role: PropTypes.string.isRequired,
301
- fullName: PropTypes.string,
302
- email: PropTypes.string,
303
- avatar: PropTypes.string,
304
- sourceProvider: PropTypes.string,
305
- connectedAccounts: PropTypes.arrayOf(
306
- PropTypes.shape({
307
- provider: PropTypes.string.isRequired,
308
- did: PropTypes.string.isRequired,
309
- id: PropTypes.string,
310
- })
311
- ),
312
- passports: PropTypes.arrayOf(
313
- PropTypes.shape({
314
- name: PropTypes.string.isRequired,
315
- title: PropTypes.string.isRequired,
316
- })
317
- ),
318
- // Deprecated
319
- extraConfigs: PropTypes.object,
320
- }),
321
- login: PropTypes.func.isRequired,
322
- logout: PropTypes.func.isRequired,
323
- switchDid: PropTypes.func.isRequired,
324
- switchProfile: PropTypes.func.isRequired,
325
- switchPassport: PropTypes.func.isRequired,
326
- bindWallet: PropTypes.func.isRequired,
327
- refresh: PropTypes.func.isRequired,
328
- }).isRequired,
329
- locale: PropTypes.string,
330
- showText: PropTypes.bool,
331
- showRole: PropTypes.bool,
332
- switchDid: PropTypes.bool,
333
- switchProfile: PropTypes.bool,
334
- switchPassport: PropTypes.bool,
335
- disableLogout: PropTypes.bool,
336
- onLogin: PropTypes.func,
337
- onLogout: PropTypes.func,
338
- onSwitchDid: PropTypes.func,
339
- onSwitchProfile: PropTypes.func,
340
- onSwitchPassport: PropTypes.func,
341
- onBindWallet: PropTypes.func,
342
- menu: PropTypes.array,
343
- menuRender: PropTypes.func,
344
- dark: PropTypes.bool,
345
- size: PropTypes.number,
346
- showManageBlocklet: PropTypes.bool,
347
- };
348
-
349
- SessionManager.defaultProps = {
350
- locale: 'en',
351
- showText: false,
352
- showRole: false,
353
- switchDid: true,
354
- switchProfile: true,
355
- switchPassport: true,
356
- disableLogout: false,
357
- menu: [],
358
- menuRender: noop,
359
- onLogin: noop,
360
- onLogout: noop,
361
- onSwitchDid: noop,
362
- onSwitchProfile: noop,
363
- onSwitchPassport: noop,
364
- onBindWallet: noop,
365
- dark: false,
366
- size: 24,
367
- showManageBlocklet: true,
368
- };
369
-
370
- export default SessionManager;
3
+ export default SessionUser;
@@ -0,0 +1,28 @@
1
+ import PropTypes from 'prop-types';
2
+ import { useCreation } from 'ahooks';
3
+
4
+ const roleList = ['owner', 'admin', 'member', 'guest'];
5
+
6
+ export default function SessionPermission({ session, roles, children }) {
7
+ const hasPermission = useCreation(() => {
8
+ return roles.includes(session?.user?.role || 'guest');
9
+ }, [session?.user?.role, roles]);
10
+
11
+ if (typeof children === 'function') {
12
+ return children({ hasPermission });
13
+ }
14
+
15
+ if (hasPermission) {
16
+ return children;
17
+ }
18
+ }
19
+
20
+ SessionPermission.propTypes = {
21
+ children: PropTypes.any.isRequired,
22
+ session: PropTypes.object.isRequired,
23
+ roles: PropTypes.arrayOf(PropTypes.oneOf(roleList)),
24
+ };
25
+
26
+ SessionPermission.defaultProps = {
27
+ roles: ['owner', 'admin'],
28
+ };