@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.
Files changed (102) hide show
  1. package/.turbo/turbo-build.log +50 -0
  2. package/.turbo/turbo-lint$colon$fix.log +8 -0
  3. package/LICENSE +13 -0
  4. package/README.md +52 -0
  5. package/build.config.ts +47 -0
  6. package/es/components/ConnectTo/connect-to.stories.d.ts +10 -0
  7. package/es/components/ConnectTo/index.d.ts +10 -0
  8. package/es/components/ConnectTo/index.js +138 -0
  9. package/es/components/PreviewNFT/index.d.ts +6 -0
  10. package/es/components/PreviewNFT/index.js +79 -0
  11. package/es/components/SpaceCard/index.d.ts +18 -0
  12. package/es/components/SpaceCard/index.js +198 -0
  13. package/es/components/SpaceCard/space-card.stories.d.ts +12 -0
  14. package/es/hooks/use-locale.d.ts +5 -0
  15. package/es/hooks/use-locale.js +14 -0
  16. package/es/hooks/use-mobile.d.ts +4 -0
  17. package/es/hooks/use-mobile.js +9 -0
  18. package/es/hooks/use-space-info.d.ts +8 -0
  19. package/es/hooks/use-space-info.js +30 -0
  20. package/es/icons/empty-space-nft.svg.js +200 -0
  21. package/es/icons/index.d.ts +4 -0
  22. package/es/icons/space-connect-error.svg.js +24 -0
  23. package/es/icons/space-connected.svg.js +24 -0
  24. package/es/icons/space-disconnect.svg.js +24 -0
  25. package/es/index.d.ts +12 -0
  26. package/es/index.js +10 -0
  27. package/es/libs/api.d.ts +2 -0
  28. package/es/libs/api.js +5 -0
  29. package/es/libs/gateway.d.ts +5 -0
  30. package/es/libs/gateway.js +44 -0
  31. package/es/libs/theme.d.ts +1 -0
  32. package/es/libs/util.d.ts +20 -0
  33. package/es/libs/util.js +58 -0
  34. package/es/locales/en.d.ts +2 -0
  35. package/es/locales/en.js +37 -0
  36. package/es/locales/index.d.ts +4 -0
  37. package/es/locales/index.js +9 -0
  38. package/es/locales/zh.d.ts +2 -0
  39. package/es/locales/zh.js +37 -0
  40. package/es/types/index.d.ts +31 -0
  41. package/es/types/index.js +9 -0
  42. package/lib/components/ConnectTo/connect-to.stories.d.ts +10 -0
  43. package/lib/components/ConnectTo/index.d.ts +10 -0
  44. package/lib/components/ConnectTo/index.js +140 -0
  45. package/lib/components/PreviewNFT/index.d.ts +6 -0
  46. package/lib/components/PreviewNFT/index.js +81 -0
  47. package/lib/components/SpaceCard/index.d.ts +18 -0
  48. package/lib/components/SpaceCard/index.js +200 -0
  49. package/lib/components/SpaceCard/space-card.stories.d.ts +12 -0
  50. package/lib/hooks/use-locale.d.ts +5 -0
  51. package/lib/hooks/use-locale.js +16 -0
  52. package/lib/hooks/use-mobile.d.ts +4 -0
  53. package/lib/hooks/use-mobile.js +11 -0
  54. package/lib/hooks/use-space-info.d.ts +8 -0
  55. package/lib/hooks/use-space-info.js +32 -0
  56. package/lib/icons/empty-space-nft.svg.js +215 -0
  57. package/lib/icons/index.d.ts +4 -0
  58. package/lib/icons/space-connect-error.svg.js +39 -0
  59. package/lib/icons/space-connected.svg.js +39 -0
  60. package/lib/icons/space-disconnect.svg.js +39 -0
  61. package/lib/index.d.ts +12 -0
  62. package/lib/index.js +32 -0
  63. package/lib/libs/api.d.ts +2 -0
  64. package/lib/libs/api.js +7 -0
  65. package/lib/libs/gateway.d.ts +5 -0
  66. package/lib/libs/gateway.js +47 -0
  67. package/lib/libs/theme.d.ts +1 -0
  68. package/lib/libs/util.d.ts +20 -0
  69. package/lib/libs/util.js +67 -0
  70. package/lib/locales/en.d.ts +2 -0
  71. package/lib/locales/en.js +39 -0
  72. package/lib/locales/index.d.ts +4 -0
  73. package/lib/locales/index.js +11 -0
  74. package/lib/locales/zh.d.ts +2 -0
  75. package/lib/locales/zh.js +39 -0
  76. package/lib/types/index.d.ts +31 -0
  77. package/lib/types/index.js +11 -0
  78. package/package.json +134 -0
  79. package/src/components/ConnectTo/connect-to.stories.tsx +11 -0
  80. package/src/components/ConnectTo/index.tsx +147 -0
  81. package/src/components/PreviewNFT/index.tsx +72 -0
  82. package/src/components/SpaceCard/index.tsx +230 -0
  83. package/src/components/SpaceCard/space-card.stories.tsx +13 -0
  84. package/src/hooks/use-locale.ts +15 -0
  85. package/src/hooks/use-mobile.ts +8 -0
  86. package/src/hooks/use-space-info.ts +32 -0
  87. package/src/icons/empty-space-nft.svg +59 -0
  88. package/src/icons/index.tsx +4 -0
  89. package/src/icons/space-connect-error.svg +4 -0
  90. package/src/icons/space-connected.svg +4 -0
  91. package/src/icons/space-disconnect.svg +4 -0
  92. package/src/index.ts +16 -0
  93. package/src/libs/api.ts +5 -0
  94. package/src/libs/gateway.ts +55 -0
  95. package/src/libs/theme.ts +18 -0
  96. package/src/libs/util.ts +86 -0
  97. package/src/locales/en.tsx +35 -0
  98. package/src/locales/index.tsx +7 -0
  99. package/src/locales/zh.tsx +35 -0
  100. package/src/types/index.ts +34 -0
  101. package/src/types/shims.d.ts +15 -0
  102. 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
@@ -0,0 +1,8 @@
1
+
2
+ > @blocklet/did-space-react@0.5.57 lint:fix /home/runner/work/did-spaces/did-spaces/packages/react
3
+ > npm run lint -- --fix
4
+
5
+
6
+ > @blocklet/did-space-react@0.5.57 lint
7
+ > tsc --noEmit && eslint src tests --ext js --ext jsx --ext ts --ext tsx --fix
8
+
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
+ ```
@@ -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 Basic from './stories/basic';
2
+ declare const _default: {
3
+ title: string;
4
+ parameters: {
5
+ layout: string;
6
+ };
7
+ tags: string[];
8
+ };
9
+ export default _default;
10
+ export { Basic };
@@ -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,6 @@
1
+ declare function PreviewSpaceNft({ src, width, height }: {
2
+ src: string;
3
+ width?: string;
4
+ height?: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
+ export default PreviewSpaceNft;
@@ -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,5 @@
1
+ declare function useLocale(): {
2
+ t: (this: any, key: any, data?: any) => any;
3
+ locale: any;
4
+ };
5
+ export default useLocale;
@@ -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 };
@@ -0,0 +1,4 @@
1
+ import { type Breakpoint } from '@mui/material/styles';
2
+ export default function useMobile({ key }?: {
3
+ key: Breakpoint | number;
4
+ }): boolean;