@arcblock/ux 2.8.26 → 2.9.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ };