@arcblock/ux 2.10.17 → 2.10.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ {
2
+ "address": "zjdu6nZFWRPuDmgPf9ouyDwcDzHgPZnQK6x9",
3
+ "display": {
4
+ "content": "http://ffd25853-znkqnawy8sak6l8hgquuy2jp4mftzf4qqc1s.did.abtnet.io/uploads/W-SR0XIzQnL2EA1o728CN.jpeg",
5
+ "type": "url"
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "address": "zjdq6X6NGfivzN22RjTD427kKSS6jE5Rmnmw",
3
+ "display": {
4
+ "content": "https://devcon.arcblock.io/workshop/api/nft/display",
5
+ "type": "url"
6
+ }
7
+ }
@@ -0,0 +1,47 @@
1
+ import axios from 'axios';
2
+ import adapter from 'axios/lib/adapters/xhr.js';
3
+ const cache = new Map();
4
+ const EXPIRATION_TIME_MS = 10 * 60 * 1000; // 10 minutes
5
+
6
+ const cacheAdapterEnhancer = config => {
7
+ const {
8
+ url,
9
+ method
10
+ } = config;
11
+ const cacheKey = JSON.stringify({
12
+ url,
13
+ method
14
+ });
15
+ if (cache.has(cacheKey)) {
16
+ const cachedResult = cache.get(cacheKey);
17
+ if (Date.now() - cachedResult.timestamp < EXPIRATION_TIME_MS) {
18
+ if (cachedResult.error) {
19
+ return Promise.reject(cachedResult.error);
20
+ }
21
+ return Promise.resolve({
22
+ headers: cachedResult.headers
23
+ });
24
+ }
25
+ cache.delete(cacheKey);
26
+ }
27
+ return adapter(config).then(response => {
28
+ // cache headers
29
+ cache.set(cacheKey, {
30
+ headers: response.headers,
31
+ timestamp: Date.now()
32
+ });
33
+ return response;
34
+ }).catch(error => {
35
+ // cache error
36
+ cache.set(cacheKey, {
37
+ error,
38
+ timestamp: Date.now()
39
+ });
40
+ throw error;
41
+ });
42
+ };
43
+ const instance = axios.create({
44
+ adapter: cacheAdapterEnhancer,
45
+ timeout: 5000
46
+ });
47
+ export default instance;
@@ -14,6 +14,7 @@ import InlineSvgEmbedder from './svg-embedder/inline-svg';
14
14
  import DefaultLoading from './loading';
15
15
  import DefaultBrokenImage from './broken';
16
16
  import { styled } from '../Theme';
17
+ import displayApi from './displayApi';
17
18
 
18
19
  /**
19
20
  * 从 assetState 中获取 nft data, 兼容新旧两种类型的数据结构, 建议将该方法的返回值传入 NFTDisplay 组件的 data prop
@@ -138,13 +139,14 @@ function NFTDisplay({
138
139
  // get url content type
139
140
  const getUrlContentType = async () => {
140
141
  try {
141
- const response = await fetch(getFullContentUrl({
142
- useImageFilter: false,
143
- t: 'nftdisplay'
144
- }), {
142
+ const response = await displayApi({
143
+ url: getFullContentUrl({
144
+ useImageFilter: false,
145
+ t: 'nftdisplay'
146
+ }),
145
147
  method: 'HEAD'
146
148
  });
147
- const contentType = response.headers.get('Content-Type');
149
+ const contentType = response?.headers?.get('Content-Type');
148
150
  setState({
149
151
  ...state,
150
152
  loadingUrlType: false,
@@ -152,6 +154,16 @@ function NFTDisplay({
152
154
  });
153
155
  } catch (error) {
154
156
  console.error('Failed to fetch url content type', error);
157
+ // display an error message when timeout occurs to avoid repeated waiting.
158
+ if (error?.message?.includes('timeout')) {
159
+ setState({
160
+ ...state,
161
+ loadingUrlType: false,
162
+ loading: false,
163
+ error: true
164
+ });
165
+ return;
166
+ }
155
167
  setState({
156
168
  ...state,
157
169
  loadingUrlType: false,
@@ -227,8 +239,8 @@ function NFTDisplay({
227
239
  onErrorCapture: onError,
228
240
  onLoad: onLoad,
229
241
  style: {
230
- width: 'auto',
231
- height: 'auto',
242
+ width: '100%',
243
+ height: '100%',
232
244
  pointerEvents: 'none'
233
245
  }
234
246
  }, url)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.10.17",
3
+ "version": "2.10.19",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -54,12 +54,12 @@
54
54
  "react": ">=18.2.0",
55
55
  "react-router-dom": ">=6.22.3"
56
56
  },
57
- "gitHead": "1c69e771a4305f01dc0070c3571364c81e8d0cb3",
57
+ "gitHead": "0cbaed2d297aa7ee7e7ebbaf7ccbc029ee3e624b",
58
58
  "dependencies": {
59
59
  "@arcblock/did-motif": "^1.1.13",
60
- "@arcblock/icons": "^2.10.17",
61
- "@arcblock/nft-display": "^2.10.17",
62
- "@arcblock/react-hooks": "^2.10.17",
60
+ "@arcblock/icons": "^2.10.19",
61
+ "@arcblock/nft-display": "^2.10.19",
62
+ "@arcblock/react-hooks": "^2.10.19",
63
63
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
64
64
  "@fontsource/inter": "^5.0.16",
65
65
  "@fontsource/ubuntu-mono": "^5.0.18",
@@ -0,0 +1,42 @@
1
+ import axios from 'axios';
2
+ import adapter from 'axios/lib/adapters/xhr.js';
3
+
4
+ const cache = new Map();
5
+ const EXPIRATION_TIME_MS = 10 * 60 * 1000; // 10 minutes
6
+
7
+ const cacheAdapterEnhancer = (config) => {
8
+ const { url, method } = config;
9
+ const cacheKey = JSON.stringify({ url, method });
10
+
11
+ if (cache.has(cacheKey)) {
12
+ const cachedResult = cache.get(cacheKey);
13
+ if (Date.now() - cachedResult.timestamp < EXPIRATION_TIME_MS) {
14
+ if (cachedResult.error) {
15
+ return Promise.reject(cachedResult.error);
16
+ }
17
+
18
+ return Promise.resolve({ headers: cachedResult.headers });
19
+ }
20
+
21
+ cache.delete(cacheKey);
22
+ }
23
+
24
+ return adapter(config)
25
+ .then((response) => {
26
+ // cache headers
27
+ cache.set(cacheKey, { headers: response.headers, timestamp: Date.now() });
28
+ return response;
29
+ })
30
+ .catch((error) => {
31
+ // cache error
32
+ cache.set(cacheKey, { error, timestamp: Date.now() });
33
+ throw error;
34
+ });
35
+ };
36
+
37
+ const instance = axios.create({
38
+ adapter: cacheAdapterEnhancer,
39
+ timeout: 5000,
40
+ });
41
+
42
+ export default instance;
@@ -15,6 +15,7 @@ import InlineSvgEmbedder from './svg-embedder/inline-svg';
15
15
  import DefaultLoading from './loading';
16
16
  import DefaultBrokenImage from './broken';
17
17
  import { styled } from '../Theme';
18
+ import displayApi from './displayApi';
18
19
 
19
20
  /**
20
21
  * 从 assetState 中获取 nft data, 兼容新旧两种类型的数据结构, 建议将该方法的返回值传入 NFTDisplay 组件的 data prop
@@ -134,13 +135,20 @@ function NFTDisplay({
134
135
  // get url content type
135
136
  const getUrlContentType = async () => {
136
137
  try {
137
- const response = await fetch(getFullContentUrl({ useImageFilter: false, t: 'nftdisplay' }), {
138
+ const response = await displayApi({
139
+ url: getFullContentUrl({ useImageFilter: false, t: 'nftdisplay' }),
138
140
  method: 'HEAD',
139
141
  });
140
- const contentType = response.headers.get('Content-Type');
142
+ const contentType = response?.headers?.get('Content-Type');
141
143
  setState({ ...state, loadingUrlType: false, urlType: contentType });
142
144
  } catch (error) {
143
145
  console.error('Failed to fetch url content type', error);
146
+ // display an error message when timeout occurs to avoid repeated waiting.
147
+ if (error?.message?.includes('timeout')) {
148
+ setState({ ...state, loadingUrlType: false, loading: false, error: true });
149
+ return;
150
+ }
151
+
144
152
  setState({ ...state, loadingUrlType: false, urlType: null });
145
153
  }
146
154
  };
@@ -201,7 +209,7 @@ function NFTDisplay({
201
209
  data={url}
202
210
  onErrorCapture={onError}
203
211
  onLoad={onLoad}
204
- style={{ width: 'auto', height: 'auto', pointerEvents: 'none' }}
212
+ style={{ width: '100%', height: '100%', pointerEvents: 'none' }}
205
213
  />
206
214
  );
207
215
  };