@blocklet/did-space-react 0.5.57
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/.turbo/turbo-build.log +50 -0
- package/.turbo/turbo-lint$colon$fix.log +8 -0
- package/LICENSE +13 -0
- package/README.md +52 -0
- package/build.config.ts +47 -0
- package/es/components/ConnectTo/connect-to.stories.d.ts +10 -0
- package/es/components/ConnectTo/index.d.ts +10 -0
- package/es/components/ConnectTo/index.js +138 -0
- package/es/components/PreviewNFT/index.d.ts +6 -0
- package/es/components/PreviewNFT/index.js +79 -0
- package/es/components/SpaceCard/index.d.ts +18 -0
- package/es/components/SpaceCard/index.js +198 -0
- package/es/components/SpaceCard/space-card.stories.d.ts +12 -0
- package/es/hooks/use-locale.d.ts +5 -0
- package/es/hooks/use-locale.js +14 -0
- package/es/hooks/use-mobile.d.ts +4 -0
- package/es/hooks/use-mobile.js +9 -0
- package/es/hooks/use-space-info.d.ts +8 -0
- package/es/hooks/use-space-info.js +30 -0
- package/es/icons/empty-space-nft.svg.js +200 -0
- package/es/icons/index.d.ts +4 -0
- package/es/icons/space-connect-error.svg.js +24 -0
- package/es/icons/space-connected.svg.js +24 -0
- package/es/icons/space-disconnect.svg.js +24 -0
- package/es/index.d.ts +12 -0
- package/es/index.js +10 -0
- package/es/libs/api.d.ts +2 -0
- package/es/libs/api.js +5 -0
- package/es/libs/gateway.d.ts +5 -0
- package/es/libs/gateway.js +44 -0
- package/es/libs/theme.d.ts +1 -0
- package/es/libs/util.d.ts +20 -0
- package/es/libs/util.js +58 -0
- package/es/locales/en.d.ts +2 -0
- package/es/locales/en.js +37 -0
- package/es/locales/index.d.ts +4 -0
- package/es/locales/index.js +9 -0
- package/es/locales/zh.d.ts +2 -0
- package/es/locales/zh.js +37 -0
- package/es/types/index.d.ts +31 -0
- package/es/types/index.js +9 -0
- package/lib/components/ConnectTo/connect-to.stories.d.ts +10 -0
- package/lib/components/ConnectTo/index.d.ts +10 -0
- package/lib/components/ConnectTo/index.js +140 -0
- package/lib/components/PreviewNFT/index.d.ts +6 -0
- package/lib/components/PreviewNFT/index.js +81 -0
- package/lib/components/SpaceCard/index.d.ts +18 -0
- package/lib/components/SpaceCard/index.js +200 -0
- package/lib/components/SpaceCard/space-card.stories.d.ts +12 -0
- package/lib/hooks/use-locale.d.ts +5 -0
- package/lib/hooks/use-locale.js +16 -0
- package/lib/hooks/use-mobile.d.ts +4 -0
- package/lib/hooks/use-mobile.js +11 -0
- package/lib/hooks/use-space-info.d.ts +8 -0
- package/lib/hooks/use-space-info.js +32 -0
- package/lib/icons/empty-space-nft.svg.js +215 -0
- package/lib/icons/index.d.ts +4 -0
- package/lib/icons/space-connect-error.svg.js +39 -0
- package/lib/icons/space-connected.svg.js +39 -0
- package/lib/icons/space-disconnect.svg.js +39 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.js +32 -0
- package/lib/libs/api.d.ts +2 -0
- package/lib/libs/api.js +7 -0
- package/lib/libs/gateway.d.ts +5 -0
- package/lib/libs/gateway.js +47 -0
- package/lib/libs/theme.d.ts +1 -0
- package/lib/libs/util.d.ts +20 -0
- package/lib/libs/util.js +67 -0
- package/lib/locales/en.d.ts +2 -0
- package/lib/locales/en.js +39 -0
- package/lib/locales/index.d.ts +4 -0
- package/lib/locales/index.js +11 -0
- package/lib/locales/zh.d.ts +2 -0
- package/lib/locales/zh.js +39 -0
- package/lib/types/index.d.ts +31 -0
- package/lib/types/index.js +11 -0
- package/package.json +134 -0
- package/src/components/ConnectTo/connect-to.stories.tsx +11 -0
- package/src/components/ConnectTo/index.tsx +147 -0
- package/src/components/PreviewNFT/index.tsx +72 -0
- package/src/components/SpaceCard/index.tsx +230 -0
- package/src/components/SpaceCard/space-card.stories.tsx +13 -0
- package/src/hooks/use-locale.ts +15 -0
- package/src/hooks/use-mobile.ts +8 -0
- package/src/hooks/use-space-info.ts +32 -0
- package/src/icons/empty-space-nft.svg +59 -0
- package/src/icons/index.tsx +4 -0
- package/src/icons/space-connect-error.svg +4 -0
- package/src/icons/space-connected.svg +4 -0
- package/src/icons/space-disconnect.svg +4 -0
- package/src/index.ts +16 -0
- package/src/libs/api.ts +5 -0
- package/src/libs/gateway.ts +55 -0
- package/src/libs/theme.ts +18 -0
- package/src/libs/util.ts +86 -0
- package/src/locales/en.tsx +35 -0
- package/src/locales/index.tsx +7 -0
- package/src/locales/zh.tsx +35 -0
- package/src/types/index.ts +34 -0
- package/src/types/shims.d.ts +15 -0
- package/vite.config.ts +32 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
> @blocklet/did-space-react@0.5.53 build /home/runner/work/did-spaces/did-spaces/packages/react
|
|
3
|
+
> unbuild && node tools/auto-exports.js && npm run cpfiles && node tools/build-types.js
|
|
4
|
+
|
|
5
|
+
[info] Building did-space-react
|
|
6
|
+
[info] Cleaning dist directory: `./lib`
|
|
7
|
+
[success] Build succeeded for did-space-react
|
|
8
|
+
[log] dist/index.js (total size: 1.35 kB, chunk size: 1.35 kB, exports: ConnectTo, PreviewNFT, SpaceCard, SpaceStatus, api, classNames, extraDIDSpacesCoreUrl, getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceDidFromEndpoint, getSpaceDidFromGatewayUrl, getSpaceGatewayUrlFromEndpoint, getSpaceNftDisplayUrlFromEndpoint, translations, useLocale, useMobile, useSpaceInfo)
|
|
9
|
+
└─ dist/libs/api.js
|
|
10
|
+
└─ dist/hooks/use-mobile.js
|
|
11
|
+
└─ dist/hooks/use-space-info.js
|
|
12
|
+
└─ dist/hooks/use-locale.js
|
|
13
|
+
└─ dist/components/SpaceCard/index.js
|
|
14
|
+
└─ dist/components/PreviewNFT/index.js
|
|
15
|
+
└─ dist/components/ConnectTo/index.js
|
|
16
|
+
└─ dist/libs/util.js
|
|
17
|
+
└─ dist/locales/index.js
|
|
18
|
+
└─ dist/types/index.js
|
|
19
|
+
|
|
20
|
+
Σ Total dist size (byte size): 1.35 kB
|
|
21
|
+
[warn] Build is done with some warnings:
|
|
22
|
+
[log]
|
|
23
|
+
[info] Building did-space-react
|
|
24
|
+
|
|
25
|
+
[info] Cleaning dist directory: `./es`
|
|
26
|
+
- Potential missing package.json files: es/index.js, es/hooks, es/components/ConnectTo/index.js, es/components/PreviewNFT/index.js, es/components/SpaceCard/index.js, es/icons/index.js, lib/icons/index.js, es/locales/index.js, es/types/index.js
|
|
27
|
+
[success] Build succeeded for did-space-react
|
|
28
|
+
[log] dist/index.js (total size: 801 B, chunk size: 801 B, exports: ConnectTo, PreviewNFT, SpaceCard, SpaceStatus, api, classNames, extraDIDSpacesCoreUrl, getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceDidFromEndpoint, getSpaceDidFromGatewayUrl, getSpaceGatewayUrlFromEndpoint, getSpaceNftDisplayUrlFromEndpoint, translations, useLocale, useMobile, useSpaceInfo)
|
|
29
|
+
└─ dist/libs/api.js
|
|
30
|
+
└─ dist/hooks/use-mobile.js
|
|
31
|
+
└─ dist/hooks/use-space-info.js
|
|
32
|
+
└─ dist/hooks/use-locale.js
|
|
33
|
+
└─ dist/components/SpaceCard/index.js
|
|
34
|
+
└─ dist/components/PreviewNFT/index.js
|
|
35
|
+
└─ dist/components/ConnectTo/index.js
|
|
36
|
+
└─ dist/libs/util.js
|
|
37
|
+
└─ dist/locales/index.js
|
|
38
|
+
└─ dist/types/index.js
|
|
39
|
+
|
|
40
|
+
Σ Total dist size (byte size): 801 B
|
|
41
|
+
[log]
|
|
42
|
+
[warn] Build is done with some warnings:
|
|
43
|
+
|
|
44
|
+
- Potential missing package.json files: es/icons/index.js, lib/icons/index.js
|
|
45
|
+
|
|
46
|
+
> @blocklet/did-space-react@0.5.53 cpfiles
|
|
47
|
+
> copyfiles -u 1 './src/**/*.css' lib/ && copyfiles -u 1 './src/**/*.css' es/
|
|
48
|
+
|
|
49
|
+
tsc --declaration --emitDeclarationOnly --outDir lib --rootDir /home/runner/work/did-spaces/did-spaces/packages/react/src
|
|
50
|
+
tsc --declaration --emitDeclarationOnly --outDir es --rootDir /home/runner/work/did-spaces/did-spaces/packages/react/src
|
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2018-2024 ArcBlock
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# DID Space Components
|
|
2
|
+
|
|
3
|
+
## SpaceCard
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
const endpoint = "https://${spaceDomain}/app/api/space/${spaceDid}/app/${appDid}/object/"
|
|
7
|
+
|
|
8
|
+
// Basic Use
|
|
9
|
+
<SpaceCard endpoint={endpoint} />
|
|
10
|
+
|
|
11
|
+
// With Action
|
|
12
|
+
<SpaceCard endpoint={endpoint} action={
|
|
13
|
+
<IconButton
|
|
14
|
+
size="small"
|
|
15
|
+
LinkComponent={Link}
|
|
16
|
+
href={getSpaceHomeUrl(spaceGateway.endpoint)}
|
|
17
|
+
target="_blank">
|
|
18
|
+
<OpenInNewIcon />
|
|
19
|
+
</IconButton>
|
|
20
|
+
}/>
|
|
21
|
+
|
|
22
|
+
// With Render Action
|
|
23
|
+
<SpaceCard
|
|
24
|
+
sx={{ marginTop: '12px', '&.selected': { borderColor: 'primary.main' } }}
|
|
25
|
+
key={x.endpoint}
|
|
26
|
+
endpoint={x.endpoint}
|
|
27
|
+
selected={x.endpoint === backupEndpoint}
|
|
28
|
+
action={({ spaceGateway, selected, compat, refresh }) => (
|
|
29
|
+
<MoreAction
|
|
30
|
+
spaceGateway={x}
|
|
31
|
+
onConnected={() => refresh()}
|
|
32
|
+
onBackedUp={() => refresh()}
|
|
33
|
+
/>
|
|
34
|
+
)}
|
|
35
|
+
/>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## ConnectTo
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
// trigger when click 'Connect with DID Wallet'
|
|
42
|
+
const onWalletConnect = () => {
|
|
43
|
+
// ...rest
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// trigger when use 'Connect using the DID Spaces gateway'
|
|
47
|
+
const onGatewayConnect = ({ spaceDid, spaceGatewayUrl }: { spaceDid: string; spaceGatewayUrl: string }) => {
|
|
48
|
+
// ...rest
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
<ConnectTo onWalletConnect={onWalletConnect} onGatewayConnect={onGatewayConnect} />;
|
|
52
|
+
```
|
package/build.config.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defineBuildConfig } from 'unbuild';
|
|
2
|
+
import svgr from '@svgr/rollup';
|
|
3
|
+
import type { BuildConfig } from 'unbuild';
|
|
4
|
+
|
|
5
|
+
const createConfig = (format: 'cjs' | 'esm'): BuildConfig => ({
|
|
6
|
+
failOnWarn: false,
|
|
7
|
+
entries: [
|
|
8
|
+
{
|
|
9
|
+
builder: 'rollup',
|
|
10
|
+
input: './src/index',
|
|
11
|
+
outDir: format === 'cjs' ? './lib' : './es',
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
clean: true,
|
|
15
|
+
externals: ['@abtnode/client'],
|
|
16
|
+
rollup: {
|
|
17
|
+
esbuild: {
|
|
18
|
+
jsx: 'automatic',
|
|
19
|
+
},
|
|
20
|
+
output: {
|
|
21
|
+
dir: format === 'cjs' ? './lib' : './es',
|
|
22
|
+
preserveModules: true,
|
|
23
|
+
preserveModulesRoot: 'src',
|
|
24
|
+
entryFileNames: '[name].js',
|
|
25
|
+
format,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
hooks: {
|
|
29
|
+
'rollup:options'(_ctx, options) {
|
|
30
|
+
// @ts-ignore
|
|
31
|
+
options.plugins.push(
|
|
32
|
+
svgr({
|
|
33
|
+
svgoConfig: {
|
|
34
|
+
plugins: [
|
|
35
|
+
{
|
|
36
|
+
name: 'removeViewBox',
|
|
37
|
+
active: false,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default defineBuildConfig([createConfig('cjs'), createConfig('esm')]);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SplitButtonProps } from '@arcblock/ux/lib/SplitButton';
|
|
2
|
+
export interface ConnectToProps extends Omit<SplitButtonProps, 'menu' | 'onClick'> {
|
|
3
|
+
onWalletConnect?: () => void;
|
|
4
|
+
onGatewayConnect?: (params: {
|
|
5
|
+
spaceDid: string;
|
|
6
|
+
spaceGatewayUrl: string;
|
|
7
|
+
}) => void;
|
|
8
|
+
}
|
|
9
|
+
declare function ConnectTo({ style, onWalletConnect, onGatewayConnect, ...rest }: ConnectToProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export default ConnectTo;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { isValid } from '@arcblock/did';
|
|
4
|
+
import { Typography, CircularProgress, DialogContentText, TextField } from '@mui/material';
|
|
5
|
+
import Button from '@arcblock/ux/lib/Button';
|
|
6
|
+
import SplitButton from '@arcblock/ux/lib/SplitButton';
|
|
7
|
+
import Dialog from '@arcblock/ux/lib/Dialog';
|
|
8
|
+
import { extraDIDSpacesCoreUrl, getSpaceDidFromGatewayUrl } from '../../libs/util.js';
|
|
9
|
+
import { getSpaceGatewayUrl, isValidSpaceGatewayUrl } from '../../libs/gateway.js';
|
|
10
|
+
import useLocale from '../../hooks/use-locale.js';
|
|
11
|
+
|
|
12
|
+
function ConnectTo({ style, onWalletConnect, onGatewayConnect, ...rest }) {
|
|
13
|
+
const { t } = useLocale();
|
|
14
|
+
const [url, setUrl] = useState("");
|
|
15
|
+
const [loading, setLoading] = useState(false);
|
|
16
|
+
const [open, setOpen] = useState(false);
|
|
17
|
+
const [errorMessage, setErrorMessage] = useState("");
|
|
18
|
+
const handleUseSpaceGatewayConnect = async () => {
|
|
19
|
+
try {
|
|
20
|
+
setLoading(true);
|
|
21
|
+
const spaceGatewayUrl = await getSpaceGatewayUrl(url);
|
|
22
|
+
const didSpacesCoreUrl = extraDIDSpacesCoreUrl(spaceGatewayUrl);
|
|
23
|
+
const spaceDid = getSpaceDidFromGatewayUrl(url);
|
|
24
|
+
if (!isValid(spaceDid) || !await isValidSpaceGatewayUrl(didSpacesCoreUrl)) {
|
|
25
|
+
throw new Error(t("storage.spaces.gateway.add.invalidUrl"));
|
|
26
|
+
}
|
|
27
|
+
onGatewayConnect?.({
|
|
28
|
+
spaceDid,
|
|
29
|
+
spaceGatewayUrl: didSpacesCoreUrl
|
|
30
|
+
});
|
|
31
|
+
setOpen(false);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
console.error(err);
|
|
34
|
+
setErrorMessage(err.message);
|
|
35
|
+
} finally {
|
|
36
|
+
setLoading(false);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const openGatewayInput = () => {
|
|
40
|
+
setErrorMessage("");
|
|
41
|
+
setUrl("");
|
|
42
|
+
setOpen(true);
|
|
43
|
+
};
|
|
44
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
SplitButton,
|
|
47
|
+
{
|
|
48
|
+
menu: [
|
|
49
|
+
// @ts-expect-error
|
|
50
|
+
/* @__PURE__ */ jsx(
|
|
51
|
+
SplitButton.Item,
|
|
52
|
+
{
|
|
53
|
+
sx: {
|
|
54
|
+
textTransform: "none"
|
|
55
|
+
},
|
|
56
|
+
onClick: openGatewayInput,
|
|
57
|
+
size: "small",
|
|
58
|
+
...rest,
|
|
59
|
+
children: t("storage.spaces.connect.useSpaceGateway")
|
|
60
|
+
},
|
|
61
|
+
"1"
|
|
62
|
+
)
|
|
63
|
+
],
|
|
64
|
+
onClick: onWalletConnect,
|
|
65
|
+
color: "primary",
|
|
66
|
+
style: { textTransform: "none !important", fontSize: "1rem", ...style },
|
|
67
|
+
size: "small",
|
|
68
|
+
...rest,
|
|
69
|
+
children: /* @__PURE__ */ jsx(Typography, { sx: { fontWeight: "bold", textTransform: "none" }, children: t("storage.spaces.connect.useWallet") })
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
/* @__PURE__ */ jsx(
|
|
73
|
+
Dialog,
|
|
74
|
+
{
|
|
75
|
+
title: t("storage.spaces.gateway.add.title"),
|
|
76
|
+
fullWidth: true,
|
|
77
|
+
maxWidth: "md",
|
|
78
|
+
open,
|
|
79
|
+
onClose: () => setOpen(false),
|
|
80
|
+
PaperProps: { style: { minHeight: "auto" } },
|
|
81
|
+
actions: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
82
|
+
/* @__PURE__ */ jsx(
|
|
83
|
+
Button,
|
|
84
|
+
{
|
|
85
|
+
variant: "outlined",
|
|
86
|
+
onClick: (e) => {
|
|
87
|
+
e.stopPropagation();
|
|
88
|
+
setOpen(false);
|
|
89
|
+
},
|
|
90
|
+
color: "inherit",
|
|
91
|
+
children: t("common.cancel")
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
/* @__PURE__ */ jsxs(
|
|
95
|
+
Button,
|
|
96
|
+
{
|
|
97
|
+
onClick: handleUseSpaceGatewayConnect,
|
|
98
|
+
color: "primary",
|
|
99
|
+
disabled: loading || !url,
|
|
100
|
+
variant: "contained",
|
|
101
|
+
autoFocus: true,
|
|
102
|
+
children: [
|
|
103
|
+
loading && /* @__PURE__ */ jsx(CircularProgress, { size: 16 }),
|
|
104
|
+
t("common.confirm")
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
] }),
|
|
109
|
+
children: /* @__PURE__ */ jsx("div", { style: { paddingTop: 12, overflowY: "hidden" }, children: /* @__PURE__ */ jsx(DialogContentText, { component: "div", children: /* @__PURE__ */ jsx(Typography, { component: "div", children: /* @__PURE__ */ jsx(
|
|
110
|
+
TextField,
|
|
111
|
+
{
|
|
112
|
+
label: t("storage.spaces.gateway.add.label"),
|
|
113
|
+
autoComplete: "off",
|
|
114
|
+
variant: "outlined",
|
|
115
|
+
name: "url",
|
|
116
|
+
fullWidth: true,
|
|
117
|
+
value: url,
|
|
118
|
+
onChange: (e) => {
|
|
119
|
+
setErrorMessage("");
|
|
120
|
+
setUrl(e.target.value);
|
|
121
|
+
},
|
|
122
|
+
disabled: loading,
|
|
123
|
+
error: Boolean(errorMessage),
|
|
124
|
+
helperText: errorMessage,
|
|
125
|
+
onKeyDown: async (e) => {
|
|
126
|
+
if (e.key === "Enter") {
|
|
127
|
+
await handleUseSpaceGatewayConnect();
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
autoFocus: true
|
|
131
|
+
}
|
|
132
|
+
) }) }) })
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
] });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export { ConnectTo as default };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Dialog, DialogContent, IconButton } from '@mui/material';
|
|
4
|
+
import CloseOutlinedIcon from '@mui/icons-material/CloseOutlined';
|
|
5
|
+
import SvgEmptySpaceNft from '../../icons/empty-space-nft.svg.js';
|
|
6
|
+
|
|
7
|
+
function PreviewSpaceNft({ src, width = "58px", height = "58px" }) {
|
|
8
|
+
const [open, setOpen] = useState(false);
|
|
9
|
+
const handleOpen = () => setOpen(true);
|
|
10
|
+
const handleClose = () => setOpen(false);
|
|
11
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "relative" }, onClick: handleOpen, children: [
|
|
13
|
+
/* @__PURE__ */ jsx("object", { data: src, width, height, children: /* @__PURE__ */ jsx(SvgEmptySpaceNft, { viewBox: "0 0 228 258", style: { cursor: "pointer", width: "64px", height: "64px" } }) }),
|
|
14
|
+
/* @__PURE__ */ jsx(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
style: {
|
|
18
|
+
position: "absolute",
|
|
19
|
+
top: 0,
|
|
20
|
+
left: 0,
|
|
21
|
+
width: "100%",
|
|
22
|
+
height: "100%",
|
|
23
|
+
zIndex: "1",
|
|
24
|
+
cursor: "pointer"
|
|
25
|
+
},
|
|
26
|
+
onClick: handleOpen
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
] }),
|
|
30
|
+
/* @__PURE__ */ jsx(
|
|
31
|
+
Dialog,
|
|
32
|
+
{
|
|
33
|
+
open,
|
|
34
|
+
onClose: handleClose,
|
|
35
|
+
"aria-labelledby": "preview-space-nft-display",
|
|
36
|
+
"aria-describedby": "preview space nft display",
|
|
37
|
+
fullWidth: true,
|
|
38
|
+
maxWidth: "md",
|
|
39
|
+
children: /* @__PURE__ */ jsxs(DialogContent, { style: { padding: "8px 8px", backgroundColor: "rgba(0,0,0,0.8)" }, children: [
|
|
40
|
+
/* @__PURE__ */ jsx(
|
|
41
|
+
IconButton,
|
|
42
|
+
{
|
|
43
|
+
color: "inherit",
|
|
44
|
+
onClick: handleClose,
|
|
45
|
+
"aria-label": "close",
|
|
46
|
+
style: { position: "absolute", top: 8, right: 8, color: "white" },
|
|
47
|
+
children: /* @__PURE__ */ jsx(CloseOutlinedIcon, {})
|
|
48
|
+
}
|
|
49
|
+
),
|
|
50
|
+
"(",
|
|
51
|
+
/* @__PURE__ */ jsx(
|
|
52
|
+
"object",
|
|
53
|
+
{
|
|
54
|
+
data: src,
|
|
55
|
+
style: {
|
|
56
|
+
width: "100%",
|
|
57
|
+
height: "75vh",
|
|
58
|
+
objectFit: "contain"
|
|
59
|
+
},
|
|
60
|
+
children: /* @__PURE__ */ jsx(
|
|
61
|
+
SvgEmptySpaceNft,
|
|
62
|
+
{
|
|
63
|
+
viewBox: "0 0 228 258",
|
|
64
|
+
style: {
|
|
65
|
+
width: "100%",
|
|
66
|
+
height: "75vh"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
")"
|
|
73
|
+
] })
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
] });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { PreviewSpaceNft as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BoxProps } from '@mui/material';
|
|
2
|
+
import { SpaceGateway, SpaceStatus } from '../../types';
|
|
3
|
+
export type Action = React.ReactNode | ((props: {
|
|
4
|
+
spaceGateway: SpaceGateway;
|
|
5
|
+
spaceStatus: SpaceStatus;
|
|
6
|
+
selected: boolean;
|
|
7
|
+
compat: boolean;
|
|
8
|
+
refresh: () => void;
|
|
9
|
+
}) => React.ReactNode);
|
|
10
|
+
export interface SpaceCardProps extends BoxProps {
|
|
11
|
+
endpoint: string;
|
|
12
|
+
selected?: boolean;
|
|
13
|
+
compat?: boolean;
|
|
14
|
+
action?: Action;
|
|
15
|
+
deps?: any[];
|
|
16
|
+
}
|
|
17
|
+
declare function SpaceCard({ endpoint, selected, compat, action, className, deps, ...rest }: SpaceCardProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export default SpaceCard;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import isUndefined from 'lodash/isUndefined';
|
|
3
|
+
import { withQuery, joinURL } from 'ufo';
|
|
4
|
+
import { Box, Stack, Link } from '@mui/material';
|
|
5
|
+
import DidAddress from '@arcblock/ux/lib/DID';
|
|
6
|
+
import { styled } from '@arcblock/ux/lib/Theme';
|
|
7
|
+
import { useState, useRef, useEffect } from 'react';
|
|
8
|
+
import useMobile from '../../hooks/use-mobile.js';
|
|
9
|
+
import useSpaceInfo from '../../hooks/use-space-info.js';
|
|
10
|
+
import useLocale from '../../hooks/use-locale.js';
|
|
11
|
+
import { getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceGatewayUrlFromEndpoint, classNames, getSpaceNftDisplayUrlFromEndpoint } from '../../libs/util.js';
|
|
12
|
+
import { SpaceStatus } from '../../types/index.js';
|
|
13
|
+
import SvgSpaceConnected from '../../icons/space-connected.svg.js';
|
|
14
|
+
import SvgSpaceDisconnect from '../../icons/space-disconnect.svg.js';
|
|
15
|
+
import SvgSpaceConnectError from '../../icons/space-connect-error.svg.js';
|
|
16
|
+
import PreviewSpaceNft from '../PreviewNFT/index.js';
|
|
17
|
+
|
|
18
|
+
function Status({
|
|
19
|
+
spaceUrl,
|
|
20
|
+
status,
|
|
21
|
+
refresh,
|
|
22
|
+
sx,
|
|
23
|
+
...rest
|
|
24
|
+
}) {
|
|
25
|
+
const { t } = useLocale();
|
|
26
|
+
const iconStyle = { marginLeft: "8px", marginRight: "4px" };
|
|
27
|
+
let icon = null;
|
|
28
|
+
let text = null;
|
|
29
|
+
if (status === SpaceStatus.CONNECTED) {
|
|
30
|
+
icon = /* @__PURE__ */ jsx(SvgSpaceConnected, { style: iconStyle });
|
|
31
|
+
text = /* @__PURE__ */ jsx("span", { style: { color: "#047857" }, children: t("storage.spaces.connected.tag") });
|
|
32
|
+
}
|
|
33
|
+
if (status === SpaceStatus.DISCONNECTED) {
|
|
34
|
+
icon = /* @__PURE__ */ jsx(SvgSpaceDisconnect, { style: iconStyle });
|
|
35
|
+
text = /* @__PURE__ */ jsx("span", { style: { color: "#626a77" }, children: t("storage.spaces.disconnected.tag") });
|
|
36
|
+
}
|
|
37
|
+
if (status === SpaceStatus.EXPIRED) {
|
|
38
|
+
icon = /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle });
|
|
39
|
+
text = /* @__PURE__ */ jsxs(Box, { component: "span", sx: { display: "flex", alignItems: "center", color: "error.main" }, children: [
|
|
40
|
+
/* @__PURE__ */ jsx("span", { children: t("storage.spaces.expired.guide") }),
|
|
41
|
+
/* @__PURE__ */ jsxs(
|
|
42
|
+
Link,
|
|
43
|
+
{
|
|
44
|
+
href: withQuery(joinURL(spaceUrl, "overview"), { guide: 1 }),
|
|
45
|
+
target: "_blank",
|
|
46
|
+
underline: "always",
|
|
47
|
+
color: "error",
|
|
48
|
+
sx: { ml: 0.5 },
|
|
49
|
+
children: [
|
|
50
|
+
"[",
|
|
51
|
+
t("common.open"),
|
|
52
|
+
"]"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
] });
|
|
57
|
+
}
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const handleVisibilityChange = () => {
|
|
60
|
+
if (!document.hidden) {
|
|
61
|
+
refresh();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
if (status === SpaceStatus.EXPIRED) {
|
|
65
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
66
|
+
} else {
|
|
67
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
68
|
+
}
|
|
69
|
+
return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
70
|
+
}, [status, refresh]);
|
|
71
|
+
return /* @__PURE__ */ jsxs(
|
|
72
|
+
Box,
|
|
73
|
+
{
|
|
74
|
+
component: "span",
|
|
75
|
+
sx: { display: "flex", alignItems: "center", color: "primary.main", fontSize: 14, ...sx },
|
|
76
|
+
...rest,
|
|
77
|
+
children: [
|
|
78
|
+
icon,
|
|
79
|
+
" ",
|
|
80
|
+
text
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
function SpaceCard({ endpoint, selected = false, compat, action, className, deps, ...rest }) {
|
|
86
|
+
const isMobile = useMobile();
|
|
87
|
+
let isCompact = compat;
|
|
88
|
+
if (isUndefined(isCompact)) {
|
|
89
|
+
isCompact = isMobile;
|
|
90
|
+
}
|
|
91
|
+
const spaceDid = getDIDSpaceDidFromEndpoint(endpoint);
|
|
92
|
+
const spaceUrl = getDIDSpaceUrlFromEndpoint(endpoint);
|
|
93
|
+
const gatewayUrl = getSpaceGatewayUrlFromEndpoint(endpoint);
|
|
94
|
+
const [refreshSpaceInfo, setRefreshSpaceInfo] = useState(false);
|
|
95
|
+
const refresh = () => setRefreshSpaceInfo((p) => !p);
|
|
96
|
+
const { data: spaceInfo, loading } = useSpaceInfo({
|
|
97
|
+
endpoint,
|
|
98
|
+
deps: [refreshSpaceInfo].concat(deps ?? [])
|
|
99
|
+
});
|
|
100
|
+
const spaceName = spaceInfo?.spaceName ?? "";
|
|
101
|
+
const hasPermission = spaceInfo?.hasPermission ?? false;
|
|
102
|
+
const isAvailable = spaceInfo?.isAvailable ?? false;
|
|
103
|
+
const spaceStatus = useRef(SpaceStatus.UNKNOWN);
|
|
104
|
+
if (spaceInfo && !loading) {
|
|
105
|
+
if (!isAvailable) {
|
|
106
|
+
spaceStatus.current = SpaceStatus.EXPIRED;
|
|
107
|
+
} else if (hasPermission) {
|
|
108
|
+
spaceStatus.current = SpaceStatus.CONNECTED;
|
|
109
|
+
} else {
|
|
110
|
+
spaceStatus.current = SpaceStatus.DISCONNECTED;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const renderAction = () => {
|
|
114
|
+
if (loading)
|
|
115
|
+
return null;
|
|
116
|
+
if (typeof action === "function") {
|
|
117
|
+
return action({
|
|
118
|
+
spaceGateway: {
|
|
119
|
+
did: spaceDid,
|
|
120
|
+
name: spaceName,
|
|
121
|
+
url: gatewayUrl,
|
|
122
|
+
endpoint
|
|
123
|
+
},
|
|
124
|
+
spaceStatus: spaceStatus.current,
|
|
125
|
+
selected,
|
|
126
|
+
compat: isCompact,
|
|
127
|
+
refresh
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return action;
|
|
131
|
+
};
|
|
132
|
+
return /* @__PURE__ */ jsxs(
|
|
133
|
+
BoxContainer,
|
|
134
|
+
{
|
|
135
|
+
className: classNames(className, {
|
|
136
|
+
selected,
|
|
137
|
+
error: spaceStatus.current === SpaceStatus.EXPIRED || spaceStatus.current === SpaceStatus.DISCONNECTED
|
|
138
|
+
}),
|
|
139
|
+
...rest,
|
|
140
|
+
children: [
|
|
141
|
+
/* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", children: [
|
|
142
|
+
/* @__PURE__ */ jsx(PreviewSpaceNft, { src: getSpaceNftDisplayUrlFromEndpoint(endpoint), width: "72px", height: "72px" }),
|
|
143
|
+
/* @__PURE__ */ jsxs(Stack, { ml: 2, flex: 1, spacing: 1, minWidth: 0, children: [
|
|
144
|
+
/* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", sx: { whiteSpace: "nowrap" }, children: [
|
|
145
|
+
/* @__PURE__ */ jsx(Box, { className: "space-name", children: spaceName }),
|
|
146
|
+
!isCompact && selected && /* @__PURE__ */ jsx(Status, { spaceUrl, status: spaceStatus.current, refresh, sx: { mr: 1 } })
|
|
147
|
+
] }),
|
|
148
|
+
/* @__PURE__ */ jsx(
|
|
149
|
+
DidAddress,
|
|
150
|
+
{
|
|
151
|
+
copyable: false,
|
|
152
|
+
size: 14,
|
|
153
|
+
compact: true,
|
|
154
|
+
responsive: false,
|
|
155
|
+
did: spaceDid,
|
|
156
|
+
sx: {
|
|
157
|
+
".did-address-text": {
|
|
158
|
+
color: "text.secondary"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
] }),
|
|
164
|
+
!isCompact && renderAction()
|
|
165
|
+
] }),
|
|
166
|
+
isCompact && /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", marginTop: 0.5, children: [
|
|
167
|
+
selected && /* @__PURE__ */ jsx(Status, { spaceUrl, status: spaceStatus.current, refresh, flex: 1 }),
|
|
168
|
+
/* @__PURE__ */ jsx(Box, { flex: 1 }),
|
|
169
|
+
renderAction()
|
|
170
|
+
] })
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
const BoxContainer = styled(Box)`
|
|
176
|
+
display: flex;
|
|
177
|
+
flex-direction: column;
|
|
178
|
+
padding: 16px;
|
|
179
|
+
box-sizing: border-box;
|
|
180
|
+
position: relative;
|
|
181
|
+
border: 1px solid ${({ theme }) => theme.palette.grey["200"] || "#f8f8f8"};
|
|
182
|
+
border-radius: 8px;
|
|
183
|
+
|
|
184
|
+
&.selected {
|
|
185
|
+
border-color: ${({ theme }) => theme.palette.primary.main || "#3b82f6"};
|
|
186
|
+
&.error {
|
|
187
|
+
border-color: ${({ theme }) => theme.palette.error.main || "#d32f2f"};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.space-name {
|
|
192
|
+
white-space: nowrap;
|
|
193
|
+
overflow: hidden;
|
|
194
|
+
text-overflow: ellipsis;
|
|
195
|
+
}
|
|
196
|
+
`;
|
|
197
|
+
|
|
198
|
+
export { SpaceCard as default };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { StoryFn } from '@storybook/react';
|
|
2
|
+
import Basic from './stories/basic';
|
|
3
|
+
declare const _default: {
|
|
4
|
+
title: string;
|
|
5
|
+
parameters: {
|
|
6
|
+
layout: string;
|
|
7
|
+
};
|
|
8
|
+
tags: string[];
|
|
9
|
+
decorators: ((Story: StoryFn) => import("react/jsx-runtime").JSX.Element)[];
|
|
10
|
+
};
|
|
11
|
+
export default _default;
|
|
12
|
+
export { Basic };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
|
+
import { translate } from '@arcblock/ux/lib/Locale/util';
|
|
3
|
+
import { useMemoizedFn } from 'ahooks';
|
|
4
|
+
import { translations } from '../locales/index.js';
|
|
5
|
+
|
|
6
|
+
function useLocale() {
|
|
7
|
+
const { locale } = useLocaleContext();
|
|
8
|
+
const t = useMemoizedFn((key, data = {}) => {
|
|
9
|
+
return translate(translations, key, locale, "en", data);
|
|
10
|
+
});
|
|
11
|
+
return { t, locale };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { useLocale as default };
|