@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,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
  };