@arcblock/ux 2.10.16 → 2.10.18
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.
|
@@ -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;
|
package/lib/NFTDisplay/index.js
CHANGED
|
@@ -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
|
|
142
|
-
|
|
143
|
-
|
|
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
|
|
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,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/ux",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.18",
|
|
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": "
|
|
57
|
+
"gitHead": "0c8a31e386a07c1d4ec78e702091d450ab4e4847",
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@arcblock/did-motif": "^1.1.13",
|
|
60
|
-
"@arcblock/icons": "^2.10.
|
|
61
|
-
"@arcblock/nft-display": "^2.10.
|
|
62
|
-
"@arcblock/react-hooks": "^2.10.
|
|
60
|
+
"@arcblock/icons": "^2.10.18",
|
|
61
|
+
"@arcblock/nft-display": "^2.10.18",
|
|
62
|
+
"@arcblock/react-hooks": "^2.10.18",
|
|
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;
|
package/src/NFTDisplay/index.js
CHANGED
|
@@ -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
|
|
138
|
+
const response = await displayApi({
|
|
139
|
+
url: getFullContentUrl({ useImageFilter: false, t: 'nftdisplay' }),
|
|
138
140
|
method: 'HEAD',
|
|
139
141
|
});
|
|
140
|
-
const contentType = response
|
|
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
|
};
|