@arcblock/ux 2.10.25 → 2.10.27
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/Header/header.js +6 -0
- package/lib/Layout/dashboard/index.js +8 -0
- package/lib/Layout/index.js +9 -1
- package/lib/SessionUser/components/logged-in.js +26 -1
- package/lib/SessionUser/libs/translation.js +4 -0
- package/package.json +6 -6
- package/src/Header/header.jsx +5 -0
- package/src/Layout/dashboard/index.jsx +7 -0
- package/src/Layout/index.jsx +8 -1
- package/src/SessionUser/components/logged-in.jsx +29 -1
- package/src/SessionUser/libs/translation.js +5 -0
package/lib/Header/header.js
CHANGED
@@ -28,6 +28,12 @@ function Header({
|
|
28
28
|
minWidth: brandWrapperMinWidth
|
29
29
|
};
|
30
30
|
useEffect(() => {
|
31
|
+
const {
|
32
|
+
searchParams
|
33
|
+
} = new URL(window.location.href);
|
34
|
+
if (searchParams.get('inviter')) {
|
35
|
+
window.localStorage.setItem('inviter', searchParams.get('inviter'));
|
36
|
+
}
|
31
37
|
if (logoRef.current) {
|
32
38
|
setBrandWrapperMinWidth(`${logoRef.current.offsetWidth}px`);
|
33
39
|
}
|
@@ -93,6 +93,14 @@ function Dashboard({
|
|
93
93
|
homeLink: defaultHomeLink,
|
94
94
|
...headerProps
|
95
95
|
};
|
96
|
+
useEffect(() => {
|
97
|
+
const {
|
98
|
+
searchParams
|
99
|
+
} = new URL(window.location.href);
|
100
|
+
if (searchParams.get('inviter')) {
|
101
|
+
window.localStorage.setItem('inviter', searchParams.get('inviter'));
|
102
|
+
}
|
103
|
+
}, []);
|
96
104
|
return /*#__PURE__*/_jsxs(Wrapper, {
|
97
105
|
...rest,
|
98
106
|
className: classes,
|
package/lib/Layout/index.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
2
|
-
import { useState } from 'react';
|
2
|
+
import { useEffect, useState } from 'react';
|
3
3
|
import PropTypes from 'prop-types';
|
4
4
|
import Helmet from 'react-helmet';
|
5
5
|
import { AppBar, Container, Drawer, Divider, IconButton, Link, List, ListItem, ListItemText, Toolbar, Typography } from '@mui/material';
|
@@ -29,6 +29,14 @@ export default function Layout({
|
|
29
29
|
const onToggleDrawer = () => {
|
30
30
|
setDrawerOpen(!drawerOpen);
|
31
31
|
};
|
32
|
+
useEffect(() => {
|
33
|
+
const {
|
34
|
+
searchParams
|
35
|
+
} = new URL(window.location.href);
|
36
|
+
if (searchParams.get('inviter')) {
|
37
|
+
window.localStorage.setItem('inviter', searchParams.get('inviter'));
|
38
|
+
}
|
39
|
+
}, []);
|
32
40
|
if (contentOnly) {
|
33
41
|
return /*#__PURE__*/_jsx(Container, {
|
34
42
|
children: children
|
@@ -1,13 +1,16 @@
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { useRef } from 'react';
|
4
|
-
import { useMemoizedFn, useReactive } from 'ahooks';
|
4
|
+
import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
|
5
5
|
import { Box, ClickAwayListener, Divider, Fade, IconButton, MenuItem, MenuList, Paper, Popper } from '@mui/material';
|
6
6
|
import { Icon } from '@iconify/react';
|
7
7
|
import PersonOutlineRoundedIcon from '@iconify-icons/material-symbols/person-outline-rounded';
|
8
8
|
import FilterVintageOutlineRoundedIcon from '@iconify-icons/material-symbols/filter-vintage-outline-rounded';
|
9
9
|
import AccountCircleOffOutlineRoundedIcon from '@iconify-icons/material-symbols/account-circle-off-outline-rounded';
|
10
|
+
import InviteIcon from '@iconify-icons/material-symbols/featured-seasonal-and-gifts-rounded';
|
11
|
+
import Copy from 'copy-to-clipboard';
|
10
12
|
import noop from 'lodash/noop';
|
13
|
+
import Toast from '../../Toast';
|
11
14
|
import DidAvatar from '../../Avatar';
|
12
15
|
import { getUserAvatar } from '../../Util';
|
13
16
|
import UserInfo from './user-info';
|
@@ -16,6 +19,11 @@ import { DASHBOARD_URL, PROFILE_URL } from '../../Util/constant';
|
|
16
19
|
import SessionPermission from '../../SessionPermission';
|
17
20
|
import { translations } from '../libs/translation';
|
18
21
|
import { translate } from '../../Locale/util';
|
22
|
+
const getInviteLink = inviter => {
|
23
|
+
const url = new URL(window.location.href);
|
24
|
+
url.searchParams.set('inviter', inviter);
|
25
|
+
return url.toString();
|
26
|
+
};
|
19
27
|
export default function LoggedIn({
|
20
28
|
session,
|
21
29
|
dark,
|
@@ -27,6 +35,9 @@ export default function LoggedIn({
|
|
27
35
|
const t = useMemoizedFn((key, data = {}) => {
|
28
36
|
return translate(translations, key, locale, 'en', data);
|
29
37
|
});
|
38
|
+
const isInviteEnabled = useCreation(() => {
|
39
|
+
return !!globalThis?.blocklet?.settings?.invite?.enabled;
|
40
|
+
});
|
30
41
|
const popperAnchorRef = useRef(null);
|
31
42
|
const currentState = useReactive({
|
32
43
|
open: false
|
@@ -69,6 +80,12 @@ export default function LoggedIn({
|
|
69
80
|
onTogglePopper(false);
|
70
81
|
session.bindWallet(onBindWallet);
|
71
82
|
});
|
83
|
+
const handleOpenInvite = useMemoizedFn(() => {
|
84
|
+
onTogglePopper(false);
|
85
|
+
const link = getInviteLink(session.user.did);
|
86
|
+
Copy(link);
|
87
|
+
Toast.success(t('inviteCopied'));
|
88
|
+
});
|
72
89
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
73
90
|
children: [/*#__PURE__*/_jsx(IconButton, {
|
74
91
|
ref: popperAnchorRef,
|
@@ -155,6 +172,14 @@ export default function LoggedIn({
|
|
155
172
|
textDecoration: 'none',
|
156
173
|
color: 'inherit'
|
157
174
|
}
|
175
|
+
}), isInviteEnabled && /*#__PURE__*/_jsx(SessionMenuItem, {
|
176
|
+
icon: InviteIcon,
|
177
|
+
title: t('invite'),
|
178
|
+
onClick: handleOpenInvite,
|
179
|
+
sx: {
|
180
|
+
display: 'block',
|
181
|
+
color: 'inherit'
|
182
|
+
}
|
158
183
|
}), /*#__PURE__*/_jsx(Divider, {
|
159
184
|
sx: {
|
160
185
|
m: '0!important',
|
@@ -4,6 +4,8 @@ export const translations = {
|
|
4
4
|
connectDIDWallet: 'Connect your DID Wallet for enhanced security',
|
5
5
|
switch: 'Switch',
|
6
6
|
profile: 'Profile',
|
7
|
+
invite: 'Invite friends',
|
8
|
+
inviteCopied: 'Your invite link has been copied to the clipboard. Send it to your friends to complete the invitation',
|
7
9
|
dashboard: 'Dashboard',
|
8
10
|
logout: 'Sign Out',
|
9
11
|
addAnotherAccount: 'Add another account'
|
@@ -12,6 +14,8 @@ export const translations = {
|
|
12
14
|
connectDIDWallet: '连接你的 DID Wallet 获得更高的安全性',
|
13
15
|
switch: '切换',
|
14
16
|
profile: '个人中心',
|
17
|
+
invite: '邀请好友',
|
18
|
+
inviteCopied: '你的专属链接已经复制到剪贴板,发送给朋友即可完成邀请',
|
15
19
|
dashboard: '控制台',
|
16
20
|
logout: '退出登录',
|
17
21
|
addAnotherAccount: '添加账户'
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.10.
|
3
|
+
"version": "2.10.27",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -59,12 +59,12 @@
|
|
59
59
|
"react": ">=18.2.0",
|
60
60
|
"react-router-dom": ">=6.22.3"
|
61
61
|
},
|
62
|
-
"gitHead": "
|
62
|
+
"gitHead": "22f8b70a73928fc915274ee0f609e96f330b1d2e",
|
63
63
|
"dependencies": {
|
64
64
|
"@arcblock/did-motif": "^1.1.13",
|
65
|
-
"@arcblock/icons": "^2.10.
|
66
|
-
"@arcblock/nft-display": "^2.10.
|
67
|
-
"@arcblock/react-hooks": "^2.10.
|
65
|
+
"@arcblock/icons": "^2.10.27",
|
66
|
+
"@arcblock/nft-display": "^2.10.27",
|
67
|
+
"@arcblock/react-hooks": "^2.10.27",
|
68
68
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
69
69
|
"@fontsource/inter": "^5.0.16",
|
70
70
|
"@fontsource/ubuntu-mono": "^5.0.18",
|
@@ -76,7 +76,7 @@
|
|
76
76
|
"@testing-library/react": "^14.0.0",
|
77
77
|
"@types/mui-datatables": "^4.3.12",
|
78
78
|
"ahooks": "^3.7.10",
|
79
|
-
"axios": "^1.7.
|
79
|
+
"axios": "^1.7.5",
|
80
80
|
"base64-url": "^2.3.3",
|
81
81
|
"copy-to-clipboard": "^3.3.2",
|
82
82
|
"core-js": "^3.25.5",
|
package/src/Header/header.jsx
CHANGED
@@ -26,6 +26,11 @@ function Header({
|
|
26
26
|
const style = { minWidth: brandWrapperMinWidth };
|
27
27
|
|
28
28
|
useEffect(() => {
|
29
|
+
const { searchParams } = new URL(window.location.href);
|
30
|
+
if (searchParams.get('inviter')) {
|
31
|
+
window.localStorage.setItem('inviter', searchParams.get('inviter'));
|
32
|
+
}
|
33
|
+
|
29
34
|
if (logoRef.current) {
|
30
35
|
setBrandWrapperMinWidth(`${logoRef.current.offsetWidth}px`);
|
31
36
|
}
|
@@ -66,6 +66,13 @@ function Dashboard({ children, title, headerProps, links = [], fullWidth, dense,
|
|
66
66
|
...headerProps,
|
67
67
|
};
|
68
68
|
|
69
|
+
useEffect(() => {
|
70
|
+
const { searchParams } = new URL(window.location.href);
|
71
|
+
if (searchParams.get('inviter')) {
|
72
|
+
window.localStorage.setItem('inviter', searchParams.get('inviter'));
|
73
|
+
}
|
74
|
+
}, []);
|
75
|
+
|
69
76
|
return (
|
70
77
|
<Wrapper {...rest} className={classes}>
|
71
78
|
<Helmet title={title} key={title} />
|
package/src/Layout/index.jsx
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { useState } from 'react';
|
1
|
+
import { useEffect, useState } from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import Helmet from 'react-helmet';
|
4
4
|
import {
|
@@ -43,6 +43,13 @@ export default function Layout({
|
|
43
43
|
setDrawerOpen(!drawerOpen);
|
44
44
|
};
|
45
45
|
|
46
|
+
useEffect(() => {
|
47
|
+
const { searchParams } = new URL(window.location.href);
|
48
|
+
if (searchParams.get('inviter')) {
|
49
|
+
window.localStorage.setItem('inviter', searchParams.get('inviter'));
|
50
|
+
}
|
51
|
+
}, []);
|
52
|
+
|
46
53
|
if (contentOnly) {
|
47
54
|
return <Container>{children}</Container>;
|
48
55
|
}
|
@@ -1,13 +1,16 @@
|
|
1
1
|
import PropTypes from 'prop-types';
|
2
2
|
import { useRef } from 'react';
|
3
|
-
import { useMemoizedFn, useReactive } from 'ahooks';
|
3
|
+
import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
|
4
4
|
import { Box, ClickAwayListener, Divider, Fade, IconButton, MenuItem, MenuList, Paper, Popper } from '@mui/material';
|
5
5
|
import { Icon } from '@iconify/react';
|
6
6
|
import PersonOutlineRoundedIcon from '@iconify-icons/material-symbols/person-outline-rounded';
|
7
7
|
import FilterVintageOutlineRoundedIcon from '@iconify-icons/material-symbols/filter-vintage-outline-rounded';
|
8
8
|
import AccountCircleOffOutlineRoundedIcon from '@iconify-icons/material-symbols/account-circle-off-outline-rounded';
|
9
|
+
import InviteIcon from '@iconify-icons/material-symbols/featured-seasonal-and-gifts-rounded';
|
10
|
+
import Copy from 'copy-to-clipboard';
|
9
11
|
import noop from 'lodash/noop';
|
10
12
|
|
13
|
+
import Toast from '../../Toast';
|
11
14
|
import DidAvatar from '../../Avatar';
|
12
15
|
import { getUserAvatar } from '../../Util';
|
13
16
|
import UserInfo from './user-info';
|
@@ -17,10 +20,19 @@ import SessionPermission from '../../SessionPermission';
|
|
17
20
|
import { translations } from '../libs/translation';
|
18
21
|
import { translate } from '../../Locale/util';
|
19
22
|
|
23
|
+
const getInviteLink = (inviter) => {
|
24
|
+
const url = new URL(window.location.href);
|
25
|
+
url.searchParams.set('inviter', inviter);
|
26
|
+
return url.toString();
|
27
|
+
};
|
28
|
+
|
20
29
|
export default function LoggedIn({ session, dark, onBindWallet, isBlocklet, locale, size }) {
|
21
30
|
const t = useMemoizedFn((key, data = {}) => {
|
22
31
|
return translate(translations, key, locale, 'en', data);
|
23
32
|
});
|
33
|
+
const isInviteEnabled = useCreation(() => {
|
34
|
+
return !!globalThis?.blocklet?.settings?.invite?.enabled;
|
35
|
+
});
|
24
36
|
const popperAnchorRef = useRef(null);
|
25
37
|
const currentState = useReactive({
|
26
38
|
open: false,
|
@@ -66,6 +78,14 @@ export default function LoggedIn({ session, dark, onBindWallet, isBlocklet, loca
|
|
66
78
|
onTogglePopper(false);
|
67
79
|
session.bindWallet(onBindWallet);
|
68
80
|
});
|
81
|
+
|
82
|
+
const handleOpenInvite = useMemoizedFn(() => {
|
83
|
+
onTogglePopper(false);
|
84
|
+
const link = getInviteLink(session.user.did);
|
85
|
+
Copy(link);
|
86
|
+
Toast.success(t('inviteCopied'));
|
87
|
+
});
|
88
|
+
|
69
89
|
return (
|
70
90
|
<>
|
71
91
|
<IconButton
|
@@ -132,6 +152,14 @@ export default function LoggedIn({ session, dark, onBindWallet, isBlocklet, loca
|
|
132
152
|
href={PROFILE_URL}
|
133
153
|
sx={{ display: 'block', textDecoration: 'none', color: 'inherit' }}
|
134
154
|
/>
|
155
|
+
{isInviteEnabled && (
|
156
|
+
<SessionMenuItem
|
157
|
+
icon={InviteIcon}
|
158
|
+
title={t('invite')}
|
159
|
+
onClick={handleOpenInvite}
|
160
|
+
sx={{ display: 'block', color: 'inherit' }}
|
161
|
+
/>
|
162
|
+
)}
|
135
163
|
<Divider sx={{ m: '0!important', borderColor: colors.strokeSep }} />
|
136
164
|
</>
|
137
165
|
) : null}
|
@@ -4,6 +4,9 @@ export const translations = {
|
|
4
4
|
connectDIDWallet: 'Connect your DID Wallet for enhanced security',
|
5
5
|
switch: 'Switch',
|
6
6
|
profile: 'Profile',
|
7
|
+
invite: 'Invite friends',
|
8
|
+
inviteCopied:
|
9
|
+
'Your invite link has been copied to the clipboard. Send it to your friends to complete the invitation',
|
7
10
|
dashboard: 'Dashboard',
|
8
11
|
logout: 'Sign Out',
|
9
12
|
addAnotherAccount: 'Add another account',
|
@@ -12,6 +15,8 @@ export const translations = {
|
|
12
15
|
connectDIDWallet: '连接你的 DID Wallet 获得更高的安全性',
|
13
16
|
switch: '切换',
|
14
17
|
profile: '个人中心',
|
18
|
+
invite: '邀请好友',
|
19
|
+
inviteCopied: '你的专属链接已经复制到剪贴板,发送给朋友即可完成邀请',
|
15
20
|
dashboard: '控制台',
|
16
21
|
logout: '退出登录',
|
17
22
|
addAnotherAccount: '添加账户',
|