@arcblock/ux 2.13.56 → 2.13.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/DIDConnect/auth-apps/auth-apps-info.d.ts +14 -0
- package/lib/DIDConnect/auth-apps/auth-apps-info.js +67 -0
- package/lib/DIDConnect/auth-apps/index.d.ts +24 -0
- package/lib/DIDConnect/auth-apps/index.js +191 -0
- package/lib/DIDConnect/index.d.ts +2 -0
- package/lib/DIDConnect/index.js +2 -1
- package/lib/DIDConnect/landing-page.d.ts +14 -0
- package/lib/DIDConnect/landing-page.js +203 -0
- package/lib/Theme/theme-provider.js +2 -0
- package/package.json +6 -6
- package/src/DIDConnect/auth-apps/auth-apps-info.tsx +75 -0
- package/src/DIDConnect/auth-apps/index.tsx +223 -0
- package/src/DIDConnect/index.ts +2 -0
- package/src/DIDConnect/landing-page.tsx +218 -0
- package/src/Theme/theme-provider.tsx +2 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
export type RequestAppInfo = {
|
2
|
+
appLogo: string;
|
3
|
+
appName: string;
|
4
|
+
appUrl: string;
|
5
|
+
};
|
6
|
+
export type CurrentAppInfo = {
|
7
|
+
appLogo: string;
|
8
|
+
appName: string;
|
9
|
+
appUrl: string;
|
10
|
+
};
|
11
|
+
export default function AuthApps({ requestAppInfo, currentAppInfo, }: {
|
12
|
+
requestAppInfo: RequestAppInfo;
|
13
|
+
currentAppInfo: CurrentAppInfo;
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
import { Box, Typography } from '@mui/material';
|
3
|
+
import Img from '../../Img';
|
4
|
+
export default function AuthApps({
|
5
|
+
requestAppInfo,
|
6
|
+
currentAppInfo
|
7
|
+
}) {
|
8
|
+
return /*#__PURE__*/_jsxs(Box, {
|
9
|
+
sx: {
|
10
|
+
textAlign: 'center',
|
11
|
+
display: 'flex',
|
12
|
+
flexDirection: 'column',
|
13
|
+
alignItems: 'center',
|
14
|
+
gap: 2
|
15
|
+
},
|
16
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
17
|
+
sx: {
|
18
|
+
display: 'flex',
|
19
|
+
alignItems: 'center',
|
20
|
+
justifyContent: 'center'
|
21
|
+
},
|
22
|
+
children: [/*#__PURE__*/_jsx(Img, {
|
23
|
+
src: currentAppInfo.appLogo,
|
24
|
+
alt: "Server",
|
25
|
+
width: 48,
|
26
|
+
height: 48
|
27
|
+
}), /*#__PURE__*/_jsxs(Box, {
|
28
|
+
sx: {
|
29
|
+
mx: 2,
|
30
|
+
display: 'flex',
|
31
|
+
alignItems: 'center',
|
32
|
+
'& .dot': {
|
33
|
+
width: 8,
|
34
|
+
height: 8,
|
35
|
+
borderRadius: '50%',
|
36
|
+
bgcolor: 'divider',
|
37
|
+
mx: 0.5
|
38
|
+
}
|
39
|
+
},
|
40
|
+
children: [/*#__PURE__*/_jsx(Box, {
|
41
|
+
className: "dot"
|
42
|
+
}), /*#__PURE__*/_jsx(Box, {
|
43
|
+
className: "dot"
|
44
|
+
}), /*#__PURE__*/_jsx(Box, {
|
45
|
+
className: "dot"
|
46
|
+
})]
|
47
|
+
}), /*#__PURE__*/_jsx(Img, {
|
48
|
+
src: requestAppInfo.appLogo,
|
49
|
+
alt: requestAppInfo.appName,
|
50
|
+
width: 48,
|
51
|
+
height: 48
|
52
|
+
})]
|
53
|
+
}), /*#__PURE__*/_jsxs(Typography, {
|
54
|
+
sx: {
|
55
|
+
mb: 1,
|
56
|
+
fontSize: '1.2rem'
|
57
|
+
},
|
58
|
+
children: ["Authorize", ' ', /*#__PURE__*/_jsx(Box, {
|
59
|
+
component: "span",
|
60
|
+
sx: {
|
61
|
+
color: 'primary.main'
|
62
|
+
},
|
63
|
+
children: requestAppInfo.appName
|
64
|
+
})]
|
65
|
+
})]
|
66
|
+
});
|
67
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import type { UserPublicInfo } from '@blocklet/js-sdk';
|
2
|
+
import { type RequestAppInfo, type CurrentAppInfo } from './auth-apps-info';
|
3
|
+
/**
|
4
|
+
* @example app/connect-to-did-space?appPid=zNKp8tdZUanWKnvhwZWvF2hKRutwM9ykLaY8&appDid=zNKp8tdZUanWKnvhwZWvF2hKRutwM9ykLaY8&appName=233&appDescription=456&appUrl=https://bbqaw5mgxc6fnihrwqcejcxvukkdgkk4anwxwk5msvm.did.abtnet.io/zh
|
5
|
+
*/
|
6
|
+
export default function AuthApps({ session, requestAppInfo, currentAppInfo, children, userInfo, hideSwitchConnect, hideAuthorize, hideCancel, notThisText, authorizeText, connectText, cancelText, useAnotherText, onConnect, onAuthorize, onSwitchConnect, onCancel, }: {
|
7
|
+
session: any;
|
8
|
+
requestAppInfo: RequestAppInfo;
|
9
|
+
currentAppInfo: CurrentAppInfo;
|
10
|
+
children?: React.ReactNode;
|
11
|
+
userInfo?: UserPublicInfo;
|
12
|
+
hideSwitchConnect?: boolean;
|
13
|
+
hideAuthorize?: boolean;
|
14
|
+
hideCancel?: boolean;
|
15
|
+
notThisText?: string;
|
16
|
+
authorizeText?: string;
|
17
|
+
connectText?: string;
|
18
|
+
cancelText?: string;
|
19
|
+
useAnotherText?: string;
|
20
|
+
onConnect?: (done: () => void) => void;
|
21
|
+
onAuthorize?: (done: () => void) => void;
|
22
|
+
onSwitchConnect?: (done: () => void) => void;
|
23
|
+
onCancel?: () => void;
|
24
|
+
}): import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,191 @@
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
import { Box, Button, CircularProgress, Link, Stack, Typography } from '@mui/material';
|
3
|
+
import { useMemoizedFn, useReactive } from 'ahooks';
|
4
|
+
import noop from 'lodash/noop';
|
5
|
+
import DIDConnectContainer from '../did-connect-container';
|
6
|
+
import AuthAppsInfo from './auth-apps-info';
|
7
|
+
import Center from '../../Center';
|
8
|
+
import LandingPage from '../landing-page';
|
9
|
+
import { translate } from '../../Locale/util';
|
10
|
+
import { useLocaleContext } from '../../Locale/context';
|
11
|
+
import UserCard from '../../UserCard';
|
12
|
+
import { CardType, InfoType } from '../../UserCard/types';
|
13
|
+
const translations = {
|
14
|
+
en: {
|
15
|
+
notThis: 'Not this?',
|
16
|
+
useAnother: 'Use another',
|
17
|
+
authorize: 'Authorize',
|
18
|
+
connect: 'Connect',
|
19
|
+
cancel: 'Cancel'
|
20
|
+
},
|
21
|
+
zh: {
|
22
|
+
notThis: '不是这个?',
|
23
|
+
useAnother: '使用其他',
|
24
|
+
authorize: '授权',
|
25
|
+
connect: 'Connect',
|
26
|
+
cancel: '取消'
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
/**
|
31
|
+
* @example app/connect-to-did-space?appPid=zNKp8tdZUanWKnvhwZWvF2hKRutwM9ykLaY8&appDid=zNKp8tdZUanWKnvhwZWvF2hKRutwM9ykLaY8&appName=233&appDescription=456&appUrl=https://bbqaw5mgxc6fnihrwqcejcxvukkdgkk4anwxwk5msvm.did.abtnet.io/zh
|
32
|
+
*/
|
33
|
+
export default function AuthApps({
|
34
|
+
session,
|
35
|
+
requestAppInfo,
|
36
|
+
currentAppInfo,
|
37
|
+
children,
|
38
|
+
userInfo,
|
39
|
+
hideSwitchConnect = false,
|
40
|
+
hideAuthorize = false,
|
41
|
+
hideCancel = false,
|
42
|
+
notThisText,
|
43
|
+
authorizeText,
|
44
|
+
connectText,
|
45
|
+
cancelText,
|
46
|
+
useAnotherText,
|
47
|
+
onConnect = noop,
|
48
|
+
onAuthorize = noop,
|
49
|
+
onSwitchConnect = noop,
|
50
|
+
onCancel = noop
|
51
|
+
}) {
|
52
|
+
const currentState = useReactive({
|
53
|
+
loading: false
|
54
|
+
});
|
55
|
+
const {
|
56
|
+
locale = 'en'
|
57
|
+
} = useLocaleContext() || {};
|
58
|
+
const t = useMemoizedFn((key, data = {}) => translate(translations, key, locale, 'en', data));
|
59
|
+
const handleCloseLoading = useMemoizedFn(() => {
|
60
|
+
currentState.loading = false;
|
61
|
+
});
|
62
|
+
const handleConnect = useMemoizedFn(() => {
|
63
|
+
currentState.loading = true;
|
64
|
+
onConnect?.(handleCloseLoading);
|
65
|
+
});
|
66
|
+
const handleSwitchConnect = useMemoizedFn(() => {
|
67
|
+
currentState.loading = true;
|
68
|
+
onSwitchConnect?.(handleCloseLoading);
|
69
|
+
});
|
70
|
+
const handleAuthorize = useMemoizedFn(() => {
|
71
|
+
currentState.loading = true;
|
72
|
+
onAuthorize?.(handleCloseLoading);
|
73
|
+
});
|
74
|
+
const handleCancel = useMemoizedFn(() => {
|
75
|
+
onCancel?.();
|
76
|
+
});
|
77
|
+
if (session.loading || !session.initialized) {
|
78
|
+
return /*#__PURE__*/_jsx(Center, {
|
79
|
+
children: /*#__PURE__*/_jsx(CircularProgress, {})
|
80
|
+
});
|
81
|
+
}
|
82
|
+
const user = userInfo ?? session?.user;
|
83
|
+
return /*#__PURE__*/_jsx(LandingPage, {
|
84
|
+
did: window.blocklet?.appPid,
|
85
|
+
standalone: true,
|
86
|
+
children: /*#__PURE__*/_jsx(Box, {
|
87
|
+
sx: {
|
88
|
+
width: 420,
|
89
|
+
maxWidth: '100%'
|
90
|
+
},
|
91
|
+
children: /*#__PURE__*/_jsx(DIDConnectContainer, {
|
92
|
+
hideCloseButton: true,
|
93
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
94
|
+
sx: {
|
95
|
+
display: 'flex',
|
96
|
+
flexDirection: 'column',
|
97
|
+
gap: 2,
|
98
|
+
p: {
|
99
|
+
xs: 2,
|
100
|
+
lg: 3,
|
101
|
+
xl: 4
|
102
|
+
},
|
103
|
+
pt: {
|
104
|
+
xs: 3,
|
105
|
+
xl: 4
|
106
|
+
},
|
107
|
+
bgcolor: 'background.paper'
|
108
|
+
},
|
109
|
+
children: [/*#__PURE__*/_jsx(AuthAppsInfo, {
|
110
|
+
requestAppInfo: requestAppInfo,
|
111
|
+
currentAppInfo: currentAppInfo
|
112
|
+
}), user ? /*#__PURE__*/_jsxs(_Fragment, {
|
113
|
+
children: [/*#__PURE__*/_jsx(UserCard, {
|
114
|
+
user: user,
|
115
|
+
showDid: true,
|
116
|
+
cardType: CardType.Detailed,
|
117
|
+
infoType: InfoType.Minimal
|
118
|
+
}), /*#__PURE__*/_jsx(Box, {})]
|
119
|
+
}) : null, children, /*#__PURE__*/_jsx(Box, {
|
120
|
+
sx: {
|
121
|
+
border: '1px solid',
|
122
|
+
borderColor: 'divider',
|
123
|
+
borderRadius: 2,
|
124
|
+
overflow: 'hidden',
|
125
|
+
my: 1
|
126
|
+
}
|
127
|
+
}), /*#__PURE__*/_jsxs(Stack, {
|
128
|
+
direction: "row",
|
129
|
+
spacing: 2,
|
130
|
+
children: [!hideCancel ? /*#__PURE__*/_jsx(Button, {
|
131
|
+
color: "inherit",
|
132
|
+
variant: "outlined",
|
133
|
+
size: "large",
|
134
|
+
fullWidth: true,
|
135
|
+
onClick: handleCancel,
|
136
|
+
sx: {
|
137
|
+
color: 'grey.500'
|
138
|
+
},
|
139
|
+
children: cancelText || t('cancel')
|
140
|
+
}) : null, user && !hideAuthorize ? /*#__PURE__*/_jsxs(Button, {
|
141
|
+
variant: "contained",
|
142
|
+
size: "large",
|
143
|
+
fullWidth: true,
|
144
|
+
onClick: handleAuthorize,
|
145
|
+
disabled: currentState.loading,
|
146
|
+
children: [currentState.loading ? /*#__PURE__*/_jsx(CircularProgress, {
|
147
|
+
size: 20,
|
148
|
+
sx: {
|
149
|
+
mr: 1
|
150
|
+
}
|
151
|
+
}) : null, authorizeText || t('authorize')]
|
152
|
+
}) : /*#__PURE__*/_jsxs(Button, {
|
153
|
+
variant: "contained",
|
154
|
+
size: "large",
|
155
|
+
fullWidth: true,
|
156
|
+
disabled: currentState.loading,
|
157
|
+
onClick: handleConnect,
|
158
|
+
children: [currentState.loading ? /*#__PURE__*/_jsx(CircularProgress, {
|
159
|
+
size: 20,
|
160
|
+
sx: {
|
161
|
+
mr: 1
|
162
|
+
}
|
163
|
+
}) : null, connectText || t('connect')]
|
164
|
+
})]
|
165
|
+
}), hideSwitchConnect || !user ? null : /*#__PURE__*/_jsx(Box, {
|
166
|
+
sx: {
|
167
|
+
textAlign: 'center'
|
168
|
+
},
|
169
|
+
children: /*#__PURE__*/_jsxs(Typography, {
|
170
|
+
variant: "body2",
|
171
|
+
sx: {
|
172
|
+
display: 'flex',
|
173
|
+
alignItems: 'center',
|
174
|
+
justifyContent: 'center',
|
175
|
+
gap: 1
|
176
|
+
},
|
177
|
+
children: [notThisText || t('notThis'), " ", /*#__PURE__*/_jsx(Link, {
|
178
|
+
underline: "hover",
|
179
|
+
onClick: handleSwitchConnect,
|
180
|
+
sx: {
|
181
|
+
cursor: 'pointer'
|
182
|
+
},
|
183
|
+
children: useAnotherText || t('useAnother')
|
184
|
+
})]
|
185
|
+
})
|
186
|
+
})]
|
187
|
+
})
|
188
|
+
})
|
189
|
+
})
|
190
|
+
});
|
191
|
+
}
|
@@ -7,3 +7,5 @@ export { default as withUxTheme } from './with-ux-theme';
|
|
7
7
|
export { default as DIDConnectLogo } from './did-connect-logo';
|
8
8
|
export { default as DIDConnectContainer } from './did-connect-container';
|
9
9
|
export { default as RequestStorageAccessApiDialog } from './request-storage-access-api-dialog';
|
10
|
+
export { default as AuthApps } from './auth-apps';
|
11
|
+
export type { RequestAppInfo, CurrentAppInfo } from './auth-apps/auth-apps-info';
|
package/lib/DIDConnect/index.js
CHANGED
@@ -6,4 +6,5 @@ export { default as withContainer } from './with-container';
|
|
6
6
|
export { default as withUxTheme } from './with-ux-theme';
|
7
7
|
export { default as DIDConnectLogo } from './did-connect-logo';
|
8
8
|
export { default as DIDConnectContainer } from './did-connect-container';
|
9
|
-
export { default as RequestStorageAccessApiDialog } from './request-storage-access-api-dialog';
|
9
|
+
export { default as RequestStorageAccessApiDialog } from './request-storage-access-api-dialog';
|
10
|
+
export { default as AuthApps } from './auth-apps';
|
@@ -0,0 +1,14 @@
|
|
1
|
+
type LandingPageProps = {
|
2
|
+
did: string;
|
3
|
+
children: React.ReactNode;
|
4
|
+
title?: any;
|
5
|
+
description?: any;
|
6
|
+
actions?: any;
|
7
|
+
logo?: any;
|
8
|
+
logoSize?: number;
|
9
|
+
poweredBy?: any;
|
10
|
+
termsOfUse?: any;
|
11
|
+
standalone?: boolean;
|
12
|
+
};
|
13
|
+
export default function LandingPage({ did, children, title, description, actions, logo, logoSize, poweredBy, termsOfUse, standalone, }: LandingPageProps): string | number | boolean | Iterable<import("react").ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
14
|
+
export {};
|
@@ -0,0 +1,203 @@
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
import { Box, Typography, useMediaQuery } from '@mui/material';
|
3
|
+
import { isEthereumDid } from '@arcblock/did';
|
4
|
+
import { getDIDMotifInfo } from '@arcblock/did-motif';
|
5
|
+
import { useCreation } from 'ahooks';
|
6
|
+
import { useTheme } from '../Theme';
|
7
|
+
import PoweredByArcBlock from '../PoweredByArcBlock';
|
8
|
+
import Avatar from '../Avatar';
|
9
|
+
import { getDIDColor, hexToRgba } from '../Util';
|
10
|
+
import useBlockletLogo from '../hooks/use-blocklet-logo';
|
11
|
+
export default function LandingPage({
|
12
|
+
did,
|
13
|
+
children,
|
14
|
+
title,
|
15
|
+
description,
|
16
|
+
actions,
|
17
|
+
logo,
|
18
|
+
logoSize = 50,
|
19
|
+
poweredBy,
|
20
|
+
termsOfUse,
|
21
|
+
standalone = false
|
22
|
+
}) {
|
23
|
+
const blockletData = globalThis?.blocklet || globalThis?.env || {};
|
24
|
+
const {
|
25
|
+
palette
|
26
|
+
} = useTheme();
|
27
|
+
const isMd = useMediaQuery(theme => theme.breakpoints.down('lg'));
|
28
|
+
const appLogo = useBlockletLogo({
|
29
|
+
meta: blockletData
|
30
|
+
});
|
31
|
+
const currentAppColor = useCreation(() => {
|
32
|
+
const _did = blockletData.appPid;
|
33
|
+
const isEthDid = isEthereumDid(_did);
|
34
|
+
const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(_did);
|
35
|
+
if (isEthDid) {
|
36
|
+
return getDIDColor(_did);
|
37
|
+
}
|
38
|
+
return didMotifInfo.color;
|
39
|
+
}, [blockletData?.appPid]);
|
40
|
+
if (!did) {
|
41
|
+
return children;
|
42
|
+
}
|
43
|
+
if (title === undefined) {
|
44
|
+
// eslint-disable-next-line no-param-reassign
|
45
|
+
title = blockletData.appName;
|
46
|
+
}
|
47
|
+
if (description === undefined) {
|
48
|
+
// eslint-disable-next-line no-param-reassign
|
49
|
+
description = blockletData.appDescription;
|
50
|
+
}
|
51
|
+
if (logo === undefined) {
|
52
|
+
// eslint-disable-next-line no-param-reassign
|
53
|
+
logo = appLogo || '';
|
54
|
+
}
|
55
|
+
if (typeof logo === 'string') {
|
56
|
+
if (logo) {
|
57
|
+
// eslint-disable-next-line no-param-reassign
|
58
|
+
logo = /*#__PURE__*/_jsx(Box, {
|
59
|
+
sx: {
|
60
|
+
height: logoSize,
|
61
|
+
maxHeight: logoSize,
|
62
|
+
objectFit: 'contain'
|
63
|
+
},
|
64
|
+
component: "img",
|
65
|
+
src: logo,
|
66
|
+
alt: `${blockletData.appName}'s logo`
|
67
|
+
});
|
68
|
+
} else {
|
69
|
+
// eslint-disable-next-line no-param-reassign
|
70
|
+
logo = /*#__PURE__*/_jsx(Avatar, {
|
71
|
+
size: logoSize,
|
72
|
+
did: did,
|
73
|
+
src: logo,
|
74
|
+
variant: "rounded"
|
75
|
+
});
|
76
|
+
}
|
77
|
+
}
|
78
|
+
if (poweredBy === undefined) {
|
79
|
+
// eslint-disable-next-line no-param-reassign
|
80
|
+
poweredBy = /*#__PURE__*/_jsx(PoweredByArcBlock, {
|
81
|
+
linkProps: {
|
82
|
+
color: palette.text.secondary,
|
83
|
+
sx: {
|
84
|
+
'&:hover': {
|
85
|
+
textDecoration: 'underline'
|
86
|
+
}
|
87
|
+
}
|
88
|
+
},
|
89
|
+
showExtra: !isMd,
|
90
|
+
sx: {
|
91
|
+
textAlign: 'center',
|
92
|
+
fontSize: '12px',
|
93
|
+
color: 'text.secondary'
|
94
|
+
}
|
95
|
+
});
|
96
|
+
}
|
97
|
+
let content = children;
|
98
|
+
if (!children && !isMd) {
|
99
|
+
content = /*#__PURE__*/_jsx(Box, {
|
100
|
+
sx: {
|
101
|
+
filter: 'blur(180px)',
|
102
|
+
display: 'flex'
|
103
|
+
},
|
104
|
+
children: /*#__PURE__*/_jsx(Avatar, {
|
105
|
+
size: 210,
|
106
|
+
did: did,
|
107
|
+
variant: "rounded"
|
108
|
+
})
|
109
|
+
});
|
110
|
+
}
|
111
|
+
const showChildren = Boolean(children);
|
112
|
+
let showInfo = !standalone;
|
113
|
+
if (isMd) {
|
114
|
+
showInfo = !showChildren;
|
115
|
+
}
|
116
|
+
return /*#__PURE__*/_jsxs(Box, {
|
117
|
+
sx: {
|
118
|
+
width: '100vw',
|
119
|
+
minHeight: '100vh',
|
120
|
+
display: 'flex',
|
121
|
+
justifyContent: 'center',
|
122
|
+
alignItems: 'center',
|
123
|
+
px: {
|
124
|
+
xs: 2,
|
125
|
+
sm: 4,
|
126
|
+
md: 8
|
127
|
+
},
|
128
|
+
pt: {
|
129
|
+
xs: 2,
|
130
|
+
sm: 4,
|
131
|
+
md: 6
|
132
|
+
},
|
133
|
+
pb: {
|
134
|
+
xs: 5,
|
135
|
+
md: 8
|
136
|
+
},
|
137
|
+
background: `radial-gradient(circle at bottom right, ${hexToRgba(currentAppColor, 0.3)} 10%, ${palette.background.default} 50%)`,
|
138
|
+
position: 'relative'
|
139
|
+
},
|
140
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
141
|
+
sx: {
|
142
|
+
maxWidth: 1200,
|
143
|
+
display: 'flex',
|
144
|
+
alignItems: 'center',
|
145
|
+
justifyContent: [showInfo, content].filter(Boolean).length > 1 ? 'space-between' : 'center',
|
146
|
+
width: '100%',
|
147
|
+
margin: 'auto'
|
148
|
+
},
|
149
|
+
children: [showInfo ? /*#__PURE__*/_jsxs(Box, {
|
150
|
+
sx: {
|
151
|
+
display: 'flex',
|
152
|
+
flexDirection: 'column',
|
153
|
+
gap: 1.5
|
154
|
+
},
|
155
|
+
children: [/*#__PURE__*/_jsx(Box, {
|
156
|
+
sx: {
|
157
|
+
display: 'flex',
|
158
|
+
alignItems: 'center'
|
159
|
+
},
|
160
|
+
children: logo
|
161
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
162
|
+
variant: "h2",
|
163
|
+
sx: {
|
164
|
+
fontWeight: 'bold',
|
165
|
+
fontSize: {
|
166
|
+
sm: '2.25rem',
|
167
|
+
md: '2.75rem',
|
168
|
+
xl: '3.5rem'
|
169
|
+
}
|
170
|
+
},
|
171
|
+
children: title
|
172
|
+
}), description ? /*#__PURE__*/_jsx(Box, {
|
173
|
+
sx: {
|
174
|
+
mb: 2,
|
175
|
+
color: 'text.secondary'
|
176
|
+
},
|
177
|
+
children: description
|
178
|
+
}) : null, actions ? /*#__PURE__*/_jsx(Box, {
|
179
|
+
sx: {
|
180
|
+
mt: 8
|
181
|
+
},
|
182
|
+
children: actions
|
183
|
+
}) : null, termsOfUse ? /*#__PURE__*/_jsx(Box, {
|
184
|
+
sx: {
|
185
|
+
mt: -1,
|
186
|
+
color: 'grey'
|
187
|
+
},
|
188
|
+
children: termsOfUse
|
189
|
+
}) : null]
|
190
|
+
}) : null, content]
|
191
|
+
}), /*#__PURE__*/_jsx(Box, {
|
192
|
+
sx: {
|
193
|
+
position: 'absolute',
|
194
|
+
zIndex: 10,
|
195
|
+
bottom: 10,
|
196
|
+
left: 10,
|
197
|
+
right: 10,
|
198
|
+
textAlign: 'center'
|
199
|
+
},
|
200
|
+
children: poweredBy
|
201
|
+
})]
|
202
|
+
});
|
203
|
+
}
|
@@ -166,11 +166,13 @@ function ColorSchemeProvider({
|
|
166
166
|
const toggleMode = useCallback(() => {
|
167
167
|
const newMode = mode === 'light' ? 'dark' : 'light';
|
168
168
|
setMode(newMode);
|
169
|
+
sessionStorage.removeItem(BLOCKLET_THEME_PREFER_KEY);
|
169
170
|
localStorage.setItem(BLOCKLET_THEME_PREFER_KEY, newMode);
|
170
171
|
}, [mode, setMode]);
|
171
172
|
const changeMode = useCallback(newMode => {
|
172
173
|
if (mode !== newMode) {
|
173
174
|
setMode(newMode);
|
175
|
+
sessionStorage.removeItem(BLOCKLET_THEME_PREFER_KEY);
|
174
176
|
localStorage.setItem(BLOCKLET_THEME_PREFER_KEY, newMode);
|
175
177
|
}
|
176
178
|
}, [mode, setMode]);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.13.
|
3
|
+
"version": "2.13.58",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -71,14 +71,14 @@
|
|
71
71
|
"react": ">=18.2.0",
|
72
72
|
"react-router-dom": ">=6.22.3"
|
73
73
|
},
|
74
|
-
"gitHead": "
|
74
|
+
"gitHead": "a1251dcb82603ceef7a4a4ab58efb3f53b103a4e",
|
75
75
|
"dependencies": {
|
76
76
|
"@arcblock/did-motif": "^1.1.13",
|
77
|
-
"@arcblock/icons": "^2.13.
|
78
|
-
"@arcblock/nft-display": "^2.13.
|
79
|
-
"@arcblock/react-hooks": "^2.13.
|
77
|
+
"@arcblock/icons": "^2.13.58",
|
78
|
+
"@arcblock/nft-display": "^2.13.58",
|
79
|
+
"@arcblock/react-hooks": "^2.13.58",
|
80
80
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
81
|
-
"@blocklet/theme": "^2.13.
|
81
|
+
"@blocklet/theme": "^2.13.58",
|
82
82
|
"@fontsource/roboto": "~5.1.1",
|
83
83
|
"@fontsource/ubuntu-mono": "^5.0.18",
|
84
84
|
"@iconify-icons/logos": "^1.2.36",
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import { Box, Typography } from '@mui/material';
|
2
|
+
import Img from '../../Img';
|
3
|
+
|
4
|
+
export type RequestAppInfo = {
|
5
|
+
appLogo: string;
|
6
|
+
appName: string;
|
7
|
+
appUrl: string;
|
8
|
+
};
|
9
|
+
|
10
|
+
export type CurrentAppInfo = {
|
11
|
+
appLogo: string;
|
12
|
+
appName: string;
|
13
|
+
appUrl: string;
|
14
|
+
};
|
15
|
+
|
16
|
+
export default function AuthApps({
|
17
|
+
requestAppInfo,
|
18
|
+
currentAppInfo,
|
19
|
+
}: {
|
20
|
+
requestAppInfo: RequestAppInfo;
|
21
|
+
currentAppInfo: CurrentAppInfo;
|
22
|
+
}) {
|
23
|
+
return (
|
24
|
+
<Box
|
25
|
+
sx={{
|
26
|
+
textAlign: 'center',
|
27
|
+
display: 'flex',
|
28
|
+
flexDirection: 'column',
|
29
|
+
alignItems: 'center',
|
30
|
+
gap: 2,
|
31
|
+
}}>
|
32
|
+
<Box
|
33
|
+
sx={{
|
34
|
+
display: 'flex',
|
35
|
+
alignItems: 'center',
|
36
|
+
justifyContent: 'center',
|
37
|
+
}}>
|
38
|
+
{/* FIXME: @zhanghan 增加 hover 的效果 */}
|
39
|
+
<Img src={currentAppInfo.appLogo} alt="Server" width={48} height={48} />
|
40
|
+
|
41
|
+
<Box
|
42
|
+
sx={{
|
43
|
+
mx: 2,
|
44
|
+
display: 'flex',
|
45
|
+
alignItems: 'center',
|
46
|
+
'& .dot': {
|
47
|
+
width: 8,
|
48
|
+
height: 8,
|
49
|
+
borderRadius: '50%',
|
50
|
+
bgcolor: 'divider',
|
51
|
+
mx: 0.5,
|
52
|
+
},
|
53
|
+
}}>
|
54
|
+
<Box className="dot" />
|
55
|
+
<Box className="dot" />
|
56
|
+
<Box className="dot" />
|
57
|
+
</Box>
|
58
|
+
|
59
|
+
{/* FIXME: @zhanghan 增加 hover 的效果 */}
|
60
|
+
<Img src={requestAppInfo.appLogo} alt={requestAppInfo.appName} width={48} height={48} />
|
61
|
+
</Box>
|
62
|
+
|
63
|
+
<Typography
|
64
|
+
sx={{
|
65
|
+
mb: 1,
|
66
|
+
fontSize: '1.2rem',
|
67
|
+
}}>
|
68
|
+
Authorize{' '}
|
69
|
+
<Box component="span" sx={{ color: 'primary.main' }}>
|
70
|
+
{requestAppInfo.appName}
|
71
|
+
</Box>
|
72
|
+
</Typography>
|
73
|
+
</Box>
|
74
|
+
);
|
75
|
+
}
|
@@ -0,0 +1,223 @@
|
|
1
|
+
import { Box, Button, CircularProgress, Link, Stack, Typography } from '@mui/material';
|
2
|
+
import { useMemoizedFn, useReactive } from 'ahooks';
|
3
|
+
import noop from 'lodash/noop';
|
4
|
+
import type { UserPublicInfo } from '@blocklet/js-sdk';
|
5
|
+
|
6
|
+
import DIDConnectContainer from '../did-connect-container';
|
7
|
+
import AuthAppsInfo, { type RequestAppInfo, type CurrentAppInfo } from './auth-apps-info';
|
8
|
+
import Center from '../../Center';
|
9
|
+
import LandingPage from '../landing-page';
|
10
|
+
import { translate } from '../../Locale/util';
|
11
|
+
import { useLocaleContext } from '../../Locale/context';
|
12
|
+
import UserCard from '../../UserCard';
|
13
|
+
import { CardType, InfoType } from '../../UserCard/types';
|
14
|
+
|
15
|
+
const translations = {
|
16
|
+
en: {
|
17
|
+
notThis: 'Not this?',
|
18
|
+
useAnother: 'Use another',
|
19
|
+
authorize: 'Authorize',
|
20
|
+
connect: 'Connect',
|
21
|
+
cancel: 'Cancel',
|
22
|
+
},
|
23
|
+
zh: {
|
24
|
+
notThis: '不是这个?',
|
25
|
+
useAnother: '使用其他',
|
26
|
+
authorize: '授权',
|
27
|
+
connect: 'Connect',
|
28
|
+
cancel: '取消',
|
29
|
+
},
|
30
|
+
};
|
31
|
+
|
32
|
+
/**
|
33
|
+
* @example app/connect-to-did-space?appPid=zNKp8tdZUanWKnvhwZWvF2hKRutwM9ykLaY8&appDid=zNKp8tdZUanWKnvhwZWvF2hKRutwM9ykLaY8&appName=233&appDescription=456&appUrl=https://bbqaw5mgxc6fnihrwqcejcxvukkdgkk4anwxwk5msvm.did.abtnet.io/zh
|
34
|
+
*/
|
35
|
+
export default function AuthApps({
|
36
|
+
session,
|
37
|
+
requestAppInfo,
|
38
|
+
currentAppInfo,
|
39
|
+
children,
|
40
|
+
userInfo,
|
41
|
+
|
42
|
+
hideSwitchConnect = false,
|
43
|
+
hideAuthorize = false,
|
44
|
+
hideCancel = false,
|
45
|
+
|
46
|
+
notThisText,
|
47
|
+
authorizeText,
|
48
|
+
connectText,
|
49
|
+
cancelText,
|
50
|
+
useAnotherText,
|
51
|
+
|
52
|
+
onConnect = noop,
|
53
|
+
onAuthorize = noop,
|
54
|
+
onSwitchConnect = noop,
|
55
|
+
onCancel = noop,
|
56
|
+
}: {
|
57
|
+
session: any;
|
58
|
+
requestAppInfo: RequestAppInfo;
|
59
|
+
currentAppInfo: CurrentAppInfo;
|
60
|
+
children?: React.ReactNode;
|
61
|
+
userInfo?: UserPublicInfo;
|
62
|
+
|
63
|
+
hideSwitchConnect?: boolean;
|
64
|
+
hideAuthorize?: boolean;
|
65
|
+
hideCancel?: boolean;
|
66
|
+
|
67
|
+
notThisText?: string;
|
68
|
+
authorizeText?: string;
|
69
|
+
connectText?: string;
|
70
|
+
cancelText?: string;
|
71
|
+
useAnotherText?: string;
|
72
|
+
|
73
|
+
onConnect?: (done: () => void) => void;
|
74
|
+
onAuthorize?: (done: () => void) => void;
|
75
|
+
onSwitchConnect?: (done: () => void) => void;
|
76
|
+
onCancel?: () => void;
|
77
|
+
}) {
|
78
|
+
const currentState = useReactive({
|
79
|
+
loading: false,
|
80
|
+
});
|
81
|
+
const { locale = 'en' } = useLocaleContext() || {};
|
82
|
+
|
83
|
+
const t = useMemoizedFn((key, data = {}) => translate(translations, key, locale, 'en', data));
|
84
|
+
|
85
|
+
const handleCloseLoading = useMemoizedFn(() => {
|
86
|
+
currentState.loading = false;
|
87
|
+
});
|
88
|
+
const handleConnect = useMemoizedFn(() => {
|
89
|
+
currentState.loading = true;
|
90
|
+
onConnect?.(handleCloseLoading);
|
91
|
+
});
|
92
|
+
const handleSwitchConnect = useMemoizedFn(() => {
|
93
|
+
currentState.loading = true;
|
94
|
+
onSwitchConnect?.(handleCloseLoading);
|
95
|
+
});
|
96
|
+
const handleAuthorize = useMemoizedFn(() => {
|
97
|
+
currentState.loading = true;
|
98
|
+
onAuthorize?.(handleCloseLoading);
|
99
|
+
});
|
100
|
+
const handleCancel = useMemoizedFn(() => {
|
101
|
+
onCancel?.();
|
102
|
+
});
|
103
|
+
|
104
|
+
if (session.loading || !session.initialized) {
|
105
|
+
return (
|
106
|
+
<Center>
|
107
|
+
<CircularProgress />
|
108
|
+
</Center>
|
109
|
+
);
|
110
|
+
}
|
111
|
+
|
112
|
+
const user = userInfo ?? session?.user;
|
113
|
+
|
114
|
+
return (
|
115
|
+
<LandingPage did={window.blocklet?.appPid} standalone>
|
116
|
+
<Box
|
117
|
+
sx={{
|
118
|
+
width: 420,
|
119
|
+
maxWidth: '100%',
|
120
|
+
}}>
|
121
|
+
<DIDConnectContainer hideCloseButton>
|
122
|
+
<Box
|
123
|
+
sx={{
|
124
|
+
display: 'flex',
|
125
|
+
flexDirection: 'column',
|
126
|
+
gap: 2,
|
127
|
+
p: {
|
128
|
+
xs: 2,
|
129
|
+
lg: 3,
|
130
|
+
xl: 4,
|
131
|
+
},
|
132
|
+
pt: {
|
133
|
+
xs: 3,
|
134
|
+
xl: 4,
|
135
|
+
},
|
136
|
+
bgcolor: 'background.paper',
|
137
|
+
}}>
|
138
|
+
<AuthAppsInfo requestAppInfo={requestAppInfo} currentAppInfo={currentAppInfo} />
|
139
|
+
|
140
|
+
{user ? (
|
141
|
+
<>
|
142
|
+
<UserCard user={user} showDid cardType={CardType.Detailed} infoType={InfoType.Minimal} />
|
143
|
+
<Box />
|
144
|
+
</>
|
145
|
+
) : null}
|
146
|
+
|
147
|
+
{children}
|
148
|
+
|
149
|
+
<Box
|
150
|
+
sx={{
|
151
|
+
border: '1px solid',
|
152
|
+
borderColor: 'divider',
|
153
|
+
borderRadius: 2,
|
154
|
+
overflow: 'hidden',
|
155
|
+
my: 1,
|
156
|
+
}}
|
157
|
+
/>
|
158
|
+
|
159
|
+
<Stack direction="row" spacing={2}>
|
160
|
+
{!hideCancel ? (
|
161
|
+
<Button
|
162
|
+
color="inherit"
|
163
|
+
variant="outlined"
|
164
|
+
size="large"
|
165
|
+
fullWidth
|
166
|
+
onClick={handleCancel}
|
167
|
+
sx={{
|
168
|
+
color: 'grey.500',
|
169
|
+
}}>
|
170
|
+
{cancelText || t('cancel')}
|
171
|
+
</Button>
|
172
|
+
) : null}
|
173
|
+
{user && !hideAuthorize ? (
|
174
|
+
<Button
|
175
|
+
variant="contained"
|
176
|
+
size="large"
|
177
|
+
fullWidth
|
178
|
+
onClick={handleAuthorize}
|
179
|
+
disabled={currentState.loading}>
|
180
|
+
{currentState.loading ? <CircularProgress size={20} sx={{ mr: 1 }} /> : null}
|
181
|
+
{authorizeText || t('authorize')}
|
182
|
+
</Button>
|
183
|
+
) : (
|
184
|
+
<Button
|
185
|
+
variant="contained"
|
186
|
+
size="large"
|
187
|
+
fullWidth
|
188
|
+
disabled={currentState.loading}
|
189
|
+
onClick={handleConnect}>
|
190
|
+
{currentState.loading ? <CircularProgress size={20} sx={{ mr: 1 }} /> : null}
|
191
|
+
{connectText || t('connect')}
|
192
|
+
</Button>
|
193
|
+
)}
|
194
|
+
</Stack>
|
195
|
+
|
196
|
+
{hideSwitchConnect || !user ? null : (
|
197
|
+
<Box sx={{ textAlign: 'center' }}>
|
198
|
+
<Typography
|
199
|
+
variant="body2"
|
200
|
+
sx={{
|
201
|
+
display: 'flex',
|
202
|
+
alignItems: 'center',
|
203
|
+
justifyContent: 'center',
|
204
|
+
gap: 1,
|
205
|
+
}}>
|
206
|
+
{notThisText || t('notThis')} {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
|
207
|
+
<Link
|
208
|
+
underline="hover"
|
209
|
+
onClick={handleSwitchConnect}
|
210
|
+
sx={{
|
211
|
+
cursor: 'pointer',
|
212
|
+
}}>
|
213
|
+
{useAnotherText || t('useAnother')}
|
214
|
+
</Link>
|
215
|
+
</Typography>
|
216
|
+
</Box>
|
217
|
+
)}
|
218
|
+
</Box>
|
219
|
+
</DIDConnectContainer>
|
220
|
+
</Box>
|
221
|
+
</LandingPage>
|
222
|
+
);
|
223
|
+
}
|
package/src/DIDConnect/index.ts
CHANGED
@@ -7,3 +7,5 @@ export { default as withUxTheme } from './with-ux-theme';
|
|
7
7
|
export { default as DIDConnectLogo } from './did-connect-logo';
|
8
8
|
export { default as DIDConnectContainer } from './did-connect-container';
|
9
9
|
export { default as RequestStorageAccessApiDialog } from './request-storage-access-api-dialog';
|
10
|
+
export { default as AuthApps } from './auth-apps';
|
11
|
+
export type { RequestAppInfo, CurrentAppInfo } from './auth-apps/auth-apps-info';
|
@@ -0,0 +1,218 @@
|
|
1
|
+
import { Box, Theme, Typography, useMediaQuery } from '@mui/material';
|
2
|
+
import { isEthereumDid } from '@arcblock/did';
|
3
|
+
import { getDIDMotifInfo } from '@arcblock/did-motif';
|
4
|
+
import { useCreation } from 'ahooks';
|
5
|
+
import { useTheme } from '../Theme';
|
6
|
+
|
7
|
+
import PoweredByArcBlock from '../PoweredByArcBlock';
|
8
|
+
import Avatar from '../Avatar';
|
9
|
+
import { getDIDColor, hexToRgba } from '../Util';
|
10
|
+
import useBlockletLogo from '../hooks/use-blocklet-logo';
|
11
|
+
|
12
|
+
type LandingPageProps = {
|
13
|
+
did: string;
|
14
|
+
children: React.ReactNode;
|
15
|
+
title?: any;
|
16
|
+
description?: any;
|
17
|
+
actions?: any;
|
18
|
+
logo?: any;
|
19
|
+
logoSize?: number;
|
20
|
+
poweredBy?: any;
|
21
|
+
termsOfUse?: any;
|
22
|
+
standalone?: boolean;
|
23
|
+
};
|
24
|
+
|
25
|
+
export default function LandingPage({
|
26
|
+
did,
|
27
|
+
children,
|
28
|
+
title,
|
29
|
+
description,
|
30
|
+
actions,
|
31
|
+
logo,
|
32
|
+
logoSize = 50,
|
33
|
+
poweredBy,
|
34
|
+
termsOfUse,
|
35
|
+
standalone = false,
|
36
|
+
}: LandingPageProps) {
|
37
|
+
const blockletData = globalThis?.blocklet || globalThis?.env || {};
|
38
|
+
const { palette } = useTheme();
|
39
|
+
const isMd = useMediaQuery((theme: Theme) => theme.breakpoints.down('lg'));
|
40
|
+
const appLogo = useBlockletLogo({
|
41
|
+
meta: blockletData,
|
42
|
+
});
|
43
|
+
const currentAppColor = useCreation(() => {
|
44
|
+
const _did = blockletData.appPid;
|
45
|
+
const isEthDid = isEthereumDid(_did);
|
46
|
+
const didMotifInfo = isEthDid ? undefined : getDIDMotifInfo(_did);
|
47
|
+
if (isEthDid) {
|
48
|
+
return getDIDColor(_did);
|
49
|
+
}
|
50
|
+
|
51
|
+
return didMotifInfo.color;
|
52
|
+
}, [blockletData?.appPid]);
|
53
|
+
|
54
|
+
if (!did) {
|
55
|
+
return children;
|
56
|
+
}
|
57
|
+
|
58
|
+
if (title === undefined) {
|
59
|
+
// eslint-disable-next-line no-param-reassign
|
60
|
+
title = blockletData.appName;
|
61
|
+
}
|
62
|
+
if (description === undefined) {
|
63
|
+
// eslint-disable-next-line no-param-reassign
|
64
|
+
description = blockletData.appDescription;
|
65
|
+
}
|
66
|
+
|
67
|
+
if (logo === undefined) {
|
68
|
+
// eslint-disable-next-line no-param-reassign
|
69
|
+
logo = appLogo || '';
|
70
|
+
}
|
71
|
+
|
72
|
+
if (typeof logo === 'string') {
|
73
|
+
if (logo) {
|
74
|
+
// eslint-disable-next-line no-param-reassign
|
75
|
+
logo = (
|
76
|
+
<Box
|
77
|
+
sx={{
|
78
|
+
height: logoSize,
|
79
|
+
maxHeight: logoSize,
|
80
|
+
objectFit: 'contain',
|
81
|
+
}}
|
82
|
+
component="img"
|
83
|
+
src={logo}
|
84
|
+
alt={`${blockletData.appName}'s logo`}
|
85
|
+
/>
|
86
|
+
);
|
87
|
+
} else {
|
88
|
+
// eslint-disable-next-line no-param-reassign
|
89
|
+
logo = <Avatar size={logoSize} did={did} src={logo} variant="rounded" />;
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
if (poweredBy === undefined) {
|
94
|
+
// eslint-disable-next-line no-param-reassign
|
95
|
+
poweredBy = (
|
96
|
+
<PoweredByArcBlock
|
97
|
+
linkProps={{
|
98
|
+
color: palette.text.secondary,
|
99
|
+
sx: {
|
100
|
+
'&:hover': {
|
101
|
+
textDecoration: 'underline',
|
102
|
+
},
|
103
|
+
},
|
104
|
+
}}
|
105
|
+
showExtra={!isMd}
|
106
|
+
sx={{
|
107
|
+
textAlign: 'center',
|
108
|
+
fontSize: '12px',
|
109
|
+
color: 'text.secondary',
|
110
|
+
}}
|
111
|
+
/>
|
112
|
+
);
|
113
|
+
}
|
114
|
+
|
115
|
+
let content = children;
|
116
|
+
if (!children && !isMd) {
|
117
|
+
content = (
|
118
|
+
<Box
|
119
|
+
sx={{
|
120
|
+
filter: 'blur(180px)',
|
121
|
+
display: 'flex',
|
122
|
+
}}>
|
123
|
+
{/* 这里只能使用 did-avatar,用于加强页面的层次感 */}
|
124
|
+
<Avatar size={210} did={did} variant="rounded" />
|
125
|
+
</Box>
|
126
|
+
);
|
127
|
+
}
|
128
|
+
|
129
|
+
const showChildren = Boolean(children);
|
130
|
+
let showInfo = !standalone;
|
131
|
+
if (isMd) {
|
132
|
+
showInfo = !showChildren;
|
133
|
+
}
|
134
|
+
|
135
|
+
return (
|
136
|
+
<Box
|
137
|
+
sx={{
|
138
|
+
width: '100vw',
|
139
|
+
minHeight: '100vh',
|
140
|
+
display: 'flex',
|
141
|
+
justifyContent: 'center',
|
142
|
+
alignItems: 'center',
|
143
|
+
px: {
|
144
|
+
xs: 2,
|
145
|
+
sm: 4,
|
146
|
+
md: 8,
|
147
|
+
},
|
148
|
+
pt: {
|
149
|
+
xs: 2,
|
150
|
+
sm: 4,
|
151
|
+
md: 6,
|
152
|
+
},
|
153
|
+
pb: {
|
154
|
+
xs: 5,
|
155
|
+
md: 8,
|
156
|
+
},
|
157
|
+
background: `radial-gradient(circle at bottom right, ${hexToRgba(currentAppColor, 0.3)} 10%, ${palette.background.default} 50%)`,
|
158
|
+
position: 'relative',
|
159
|
+
}}>
|
160
|
+
<Box
|
161
|
+
sx={{
|
162
|
+
maxWidth: 1200,
|
163
|
+
display: 'flex',
|
164
|
+
alignItems: 'center',
|
165
|
+
justifyContent: [showInfo, content].filter(Boolean).length > 1 ? 'space-between' : 'center',
|
166
|
+
width: '100%',
|
167
|
+
margin: 'auto',
|
168
|
+
}}>
|
169
|
+
{showInfo ? (
|
170
|
+
<Box
|
171
|
+
sx={{
|
172
|
+
display: 'flex',
|
173
|
+
flexDirection: 'column',
|
174
|
+
gap: 1.5,
|
175
|
+
}}>
|
176
|
+
<Box sx={{ display: 'flex', alignItems: 'center' }}>{logo}</Box>
|
177
|
+
<Typography
|
178
|
+
variant="h2"
|
179
|
+
sx={{
|
180
|
+
fontWeight: 'bold',
|
181
|
+
fontSize: {
|
182
|
+
sm: '2.25rem',
|
183
|
+
md: '2.75rem',
|
184
|
+
xl: '3.5rem',
|
185
|
+
},
|
186
|
+
}}>
|
187
|
+
{title}
|
188
|
+
</Typography>
|
189
|
+
{description ? (
|
190
|
+
<Box
|
191
|
+
sx={{
|
192
|
+
mb: 2,
|
193
|
+
color: 'text.secondary',
|
194
|
+
}}>
|
195
|
+
{description}
|
196
|
+
</Box>
|
197
|
+
) : null}
|
198
|
+
{actions ? <Box sx={{ mt: 8 }}>{actions}</Box> : null}
|
199
|
+
{termsOfUse ? <Box sx={{ mt: -1, color: 'grey' }}>{termsOfUse}</Box> : null}
|
200
|
+
</Box>
|
201
|
+
) : null}
|
202
|
+
|
203
|
+
{content}
|
204
|
+
</Box>
|
205
|
+
<Box
|
206
|
+
sx={{
|
207
|
+
position: 'absolute',
|
208
|
+
zIndex: 10,
|
209
|
+
bottom: 10,
|
210
|
+
left: 10,
|
211
|
+
right: 10,
|
212
|
+
textAlign: 'center',
|
213
|
+
}}>
|
214
|
+
{poweredBy}
|
215
|
+
</Box>
|
216
|
+
</Box>
|
217
|
+
);
|
218
|
+
}
|
@@ -195,6 +195,7 @@ function ColorSchemeProvider({
|
|
195
195
|
const toggleMode = useCallback(() => {
|
196
196
|
const newMode = mode === 'light' ? 'dark' : 'light';
|
197
197
|
setMode(newMode);
|
198
|
+
sessionStorage.removeItem(BLOCKLET_THEME_PREFER_KEY);
|
198
199
|
localStorage.setItem(BLOCKLET_THEME_PREFER_KEY, newMode);
|
199
200
|
}, [mode, setMode]);
|
200
201
|
|
@@ -202,6 +203,7 @@ function ColorSchemeProvider({
|
|
202
203
|
(newMode: PaletteMode) => {
|
203
204
|
if (mode !== newMode) {
|
204
205
|
setMode(newMode);
|
206
|
+
sessionStorage.removeItem(BLOCKLET_THEME_PREFER_KEY);
|
205
207
|
localStorage.setItem(BLOCKLET_THEME_PREFER_KEY, newMode);
|
206
208
|
}
|
207
209
|
},
|