@arcblock/ux 2.10.16 → 2.10.18

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,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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.10.16",
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": "4e446d45fbf0db374ffe0ebc9ba0b9dce08fbe0a",
57
+ "gitHead": "0c8a31e386a07c1d4ec78e702091d450ab4e4847",
58
58
  "dependencies": {
59
59
  "@arcblock/did-motif": "^1.1.13",
60
- "@arcblock/icons": "^2.10.16",
61
- "@arcblock/nft-display": "^2.10.16",
62
- "@arcblock/react-hooks": "^2.10.16",
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;
@@ -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
  };