@conecli/cone-render 0.10.1-beta.7 → 0.10.1-beta.9

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 (75) hide show
  1. package/dist/api/index.ts +1 -1
  2. package/dist/common/const.ts +1 -1
  3. package/dist/common/index.h5.ts +1 -1
  4. package/dist/common/index.jd.ts +1 -1
  5. package/dist/common/index.ts +1 -1
  6. package/dist/common/index.weapp.ts +1 -1
  7. package/dist/common/token/index.h5.ts +1 -1
  8. package/dist/common/token/token.jd.ts +1 -1
  9. package/dist/common/wxappApi.ts +1 -1
  10. package/dist/components/base/CommonFloorHead/index.module.scss +126 -111
  11. package/dist/components/base/CommonFloorHead/index.tsx +1 -1
  12. package/dist/components/base/CustomScrollView/index.tsx +1 -1
  13. package/dist/components/base/Dialog/index.module.scss +11 -0
  14. package/dist/components/base/ExposureSmart/index.h5.module.scss +12 -2
  15. package/dist/components/base/ExposureSmart/index.h5.tsx +1 -1
  16. package/dist/components/base/ExposureSmart/reporter.tsx +1 -1
  17. package/dist/components/base/InOrOutViewObserver/index.tsx +1 -1
  18. package/dist/components/base/InViewRender/index.weapp.tsx +1 -1
  19. package/dist/components/base/ItemViewExposureSmart/index.module.scss +2 -2
  20. package/dist/components/base/ItemViewExposureSmart/index.tsx +1 -1
  21. package/dist/components/base/LazyLayoutLoad/index.tsx +1 -1
  22. package/dist/components/base/LazyLayoutLoad/index.weapp.tsx +1 -1
  23. package/dist/components/base/LazyLoadImage/index.h5.module.scss +4 -8
  24. package/dist/components/base/LazyLoadImage/index.h5.tsx +1 -1
  25. package/dist/components/base/LazyLoadImage/index.tsx +1 -1
  26. package/dist/components/base/NetworkDataError/index.tsx +1 -1
  27. package/dist/components/decorate/PlaceHolder/index.tsx +1 -1
  28. package/dist/components/floorItem.jd.tsx +1 -1
  29. package/dist/components/floorItem.tsx +1 -1
  30. package/dist/components/floorItem.weapp.tsx +1 -1
  31. package/dist/interface/common.ts +1 -1
  32. package/dist/interface/component.ts +1 -1
  33. package/dist/interface/jumpEventReport.ts +1 -1
  34. package/dist/interface/service.ts +1 -1
  35. package/dist/jumpEventReport/base.ts +1 -1
  36. package/dist/jumpEventReport/const.ts +1 -1
  37. package/dist/jumpEventReport/index.weapp.ts +1 -1
  38. package/dist/jumpEventReport/jdJumpJdApp.ts +1 -1
  39. package/dist/jumpEventReport/jumpUrlConfig/base.ts +1 -1
  40. package/dist/jumpEventReport/logEventConfig.ts +1 -1
  41. package/dist/jumpEventReport/web/report.ts +1 -1
  42. package/dist/jumpEventReport/web.base.ts +1 -1
  43. package/dist/jumpEventReport/web.jd.ts +1 -1
  44. package/dist/jumpEventReport/web.tjm.ts +1 -1
  45. package/dist/jumpEventReport/web.wxapp.ts +1 -1
  46. package/dist/libs/taroAppReport.js +2 -2
  47. package/dist/modules/ContainerFloorList/index.h5.module.scss +66 -53
  48. package/dist/modules/ContainerFloorList/index.h5.tsx +1 -1
  49. package/dist/modules/ContainerFloorList/index.tsx +1 -1
  50. package/dist/open/api/device.ts +1 -1
  51. package/dist/open/api/environment.ts +1 -1
  52. package/dist/open/api/shopMember.ts +1 -1
  53. package/dist/open/api/util.ts +1 -1
  54. package/dist/sass/app.h5.scss +255 -224
  55. package/dist/service/fetchGateway.ts +1 -1
  56. package/dist/service/fetchGateway.weapp.ts +1 -0
  57. package/dist/service/http/colorSign.ts +1 -1
  58. package/dist/service/http/const.ts +1 -1
  59. package/dist/service/http/h5Http.ts +1 -1
  60. package/dist/service/requestServer.h5.ts +1 -1
  61. package/dist/service/requestServer.ts +1 -1
  62. package/dist/service/requestServer.weapp.ts +1 -0
  63. package/dist/utils/connectNativeJsBridge.ts +1 -1
  64. package/dist/utils/h5Utils.ts +1 -1
  65. package/dist/utils/index.h5.ts +1 -1
  66. package/dist/utils/index.ts +1 -1
  67. package/dist/utils/index.weapp.ts +1 -1
  68. package/dist/utils/jumpExtMapUtil.h5.ts +1 -0
  69. package/dist/utils/jumpExtMapUtil.ts +1 -0
  70. package/dist/utils/sColor.js +1 -0
  71. package/dist/utils/taroRenderUtil.ts +1 -1
  72. package/dist/utils/utils.ts +1 -1
  73. package/dist/wxapp/common/address_api/address_api_v2.js +1 -0
  74. package/dist/wxapp/common/user_info.js +1 -1
  75. package/package.json +147 -141
@@ -1 +1 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react'
2
1
  getQualityImage,
3
2
  isH5AndJdShopView,
4
3
  isChartH5,
5
4
  isH5AndJdShopViewH5Scroll,
6
5
  isAppStowShop,
7
6
  getSgmCustomCode,
8
7
  sgmCustomReport,
9
8
  isImageOptimizeEnable,
10
9
  getAvifSupport,
11
10
  getWebpSupport,
12
11
  getNativePageScrollRes,
13
12
  latestFromNativeMsgStorage,
14
13
  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAANQTFRFAAAAp3o92gAAAAF0Uk5TAEDm2GYAAAAKSURBVHicY2QAAAAEAAIhZK1qAAAAAElFTkSuQmCC'
15
14
  'https://img14.360buyimg.com/imagetools/jfs/t1/222907/25/7012/5824/61c4797cEbcd17c7f/6c76fc71e4fdb5a5.png'
16
15
  const styleSheets = document.styleSheets
17
16
  const internalStyleSheets = []
18
17
  for (let i = 0; i < styleSheets.length; i++) {
19
18
  const sheet = styleSheets[i]
20
19
  const ownerNode = sheet.ownerNode
21
20
  if (ownerNode && ownerNode.nodeName === 'STYLE') {
22
21
  internalStyleSheets.push(sheet)
23
22
  }
24
23
  }
25
24
  console.warn(
26
25
  '🚗 ~~ file: index.h5.tsx:47 ~~ getRuleBySelector() ~~ selector:',
27
26
  selector,
28
27
  )
29
28
  for (let i = 0; i < internalStyleSheets.length; i++) {
30
29
  try {
31
30
  const sheet = internalStyleSheets[i]
32
31
  const rules = sheet.cssRules || sheet.rules
33
32
  for (const rule of rules) {
34
33
  if (rule?.selectorText?.match(new RegExp(selector + '$'))) {
35
34
  return rule
36
35
  }
37
36
  }
38
37
  } catch (e) {
39
38
  console.warn('因安全限制无法访问样式表:', e)
40
39
  }
41
40
  }
42
41
  return null
43
42
  const {
44
43
  src = null,
45
44
  lazyLoad = true,
46
45
  imagRenderingSet = true,
47
46
  width = null,
48
47
  height = null,
49
48
  className = null,
50
49
  isSkuImage = false,
51
50
  hideErrorImage = false,
52
51
  style = null,
53
52
  backgroundColor = null,
54
53
  errorSrc = null,
55
54
  onLoad = null,
56
55
  onError = null,
57
56
  ...otherOption
58
57
  } = props
59
58
  getNetWorkType === NetWorkTypeQuality.default &&
60
59
  (getNetWorkType = global.info.sysInfo.netWorkType)
61
60
  const [loadSuccess, setLoadSuccess] = useState(false)
62
61
  const [imageErrState, setImageErrState] = useState(false)
63
62
  const [componentShowState, setComponentShowState] = useState(false)
64
63
  const measureRef = useRef<HTMLElement | null>(null)
65
64
  const [measureComplete, setMeasureComplete] = useState(false)
66
65
  const [imgSrc, setImgSrc] = useState(src)
67
66
  const [hasRetrySuccess, setHasRetrySuccess] = useState(false)
68
67
  const hasRetryRef = useRef(false)
69
68
  const componentShowStateRef = useRef(false)
70
69
  const requestSrcRef = useRef(src)
71
70
  const needShowHighVersion =
72
71
  isH5AndJdShopViewH5Scroll &&
73
72
  !(
74
73
  global.info.queryInfo?.downgraded &&
75
74
  global.info.queryInfo.downgraded === 'true'
76
75
  )
77
76
  const enableAvifOptimize = isImageOptimizeEnable()
78
77
  const isVipShop = global?.info?.pageInfo?.isVipShop
79
78
  const avifSupport = getAvifSupport()
80
79
  const webpSupport = getWebpSupport()
81
80
 
82
81
  const getRequestSrc = useCallback(
83
82
  (src) => {
84
83
  const requestSrc = getQualityImage(imgSrc, {
85
84
  isSkuImage,
86
85
  size: measureRef?.current?.getBoundingClientRect()?.width,
87
86
  })
88
87
  requestSrcRef.current = requestSrc
89
88
  return requestSrc
90
89
  },
91
90
  [src],
92
91
  )
93
92
 
94
93
  const imageErrorRetry = (src) => {
95
94
  return new Promise((resolve, reject) => {
96
95
  if (fetch && window && window.Image) {
97
96
  fetch(src)
98
97
  .then((response) => {
99
98
  const { ok, status } = response
100
99
  if (ok) {
101
100
  const originUrl = src.replace(/\.(jpe?g|png).*/, '.$1')
102
101
  response
103
102
  .blob()
104
103
  .then((blob) => {
105
104
  if (URL) {
106
105
  const url = URL.createObjectURL(blob)
107
106
  const img = new window.Image()
108
107
  img.src = url
109
108
  img.onload = () => {
110
109
  reportSGM({
111
110
  status,
112
111
  text: '再次请求并且onload了',
113
112
  type: 'retryAndOnload',
114
113
  requestSrc: src,
115
114
  resolveUrl: url,
116
115
  })
117
116
  resolve({
118
117
  ok: true,
119
118
  url,
120
119
  })
121
120
  setTimeout(() => {
122
121
  URL.revokeObjectURL(url)
123
122
  }, 2000)
124
123
  }
125
124
  img.onerror = () => {
126
125
  reportSGM({
127
126
  status,
128
127
  text: '图片解析异常',
129
128
  type: 'imageParseError',
130
129
  requestSrc: src,
131
130
  })
132
131
  URL.revokeObjectURL(url)
133
132
  resolve({
134
133
  ok: true,
135
134
  url: originUrl,
136
135
  })
137
136
  }
138
137
  } else {
139
138
  resolve({
140
139
  ok: true,
141
140
  url: originUrl,
142
141
  })
143
142
  }
144
143
  })
145
144
  .catch((error) => {
146
145
  resolve({
147
146
  ok: true,
148
147
  url: originUrl,
149
148
  })
150
149
  console.error('LazyLoadImage imageErrorRetry() error:', error)
151
150
  })
152
151
  } else {
153
152
  if (status === 404) {
154
153
  resolve({
155
154
  ok: false,
156
155
  text: '访问图片不存在',
157
156
  type: 'noSuchUrlImage',
158
157
  })
159
158
  } else {
160
159
  resolve({
161
160
  ok: false,
162
161
  status: status,
163
162
  text: '其它图片问题',
164
163
  type: 'otherImageError',
165
164
  })
166
165
  }
167
166
  }
168
167
  })
169
168
  .catch((error) => {
170
169
  resolve({
171
170
  ok: false,
172
171
  text: '网络异常',
173
172
  type: 'networkError',
174
173
  })
175
174
  console.error('LazyLoadImage imageErrorRetry() error:', error)
176
175
  })
177
176
  } else {
178
177
  resolve({
179
178
  ok: false,
180
179
  text: '不支持重试',
181
180
  type: 'notSupportRetry',
182
181
  })
183
182
  }
184
183
  })
185
184
  }
186
185
 
187
186
  const reportSGM = ({
188
187
  status,
189
188
  text,
190
189
  type,
191
190
  requestSrc = imgSrc,
192
191
  resolveUrl = '',
193
192
  }) => {
194
193
  const { shopId, venderId } = global.info.queryInfo || {}
195
194
  sgmCustomReport({
196
195
  code: getSgmCustomCode(`${SgmCustomCode.IMAGE_LOAD}_${type}`),
197
196
  msg: {
198
197
  avifSupport,
199
198
  webpSupport,
200
199
  shopId,
201
200
  venderId,
202
201
  originSrc: src,
203
202
  requestSrc,
204
203
  resolveUrl,
205
204
  status,
206
205
  text,
207
206
  },
208
207
  })
209
208
  }
210
209
  const imageErrorHandle = useCallback(
211
210
  (e) => {
212
211
  console.log(' ==============> 图片加载错误', e)
213
212
  if (!hasRetryRef.current) {
214
213
  hasRetryRef.current = true
215
214
  if (src) {
216
215
  try {
217
216
  imageErrorRetry(requestSrcRef.current).then((result) => {
218
217
  const { status, ok, text, type, url } = result || {}
219
218
  if (ok) {
220
219
  setImgSrc(url)
221
220
  setHasRetrySuccess(true)
222
221
  } else {
223
222
  errorSrc && setImgSrc(errorSrc)
224
223
  hideErrorImage && setImageErrState(true)
225
224
  typeof onError === 'function' && onError(e, src, props)
226
225
  reportSGM({
227
226
  status,
228
227
  text,
229
228
  type,
230
229
  requestSrc: requestSrcRef.current,
231
230
  })
232
231
  }
233
232
  })
234
233
  } catch (e) {
235
234
  console.error('LazyLoadImage imageErrorHandle() error:', e)
236
235
  errorSrc && setImgSrc(errorSrc)
237
236
  hideErrorImage && setImageErrState(true)
238
237
  typeof onError === 'function' && onError(e, src, props)
239
238
  }
240
239
  }
241
240
  } else {
242
241
  reportSGM({
243
242
  status: '',
244
243
  text: '渲染原始图片渲染异常',
245
244
  type: 'renderOriginImageError',
246
245
  })
247
246
  if (imgSrc.includes('blob:')) {
248
247
  reportSGM({
249
248
  status: '',
250
249
  text: '渲染本地blob图片异常',
251
250
  type: 'renderBlobImageError',
252
251
  })
253
252
  } else {
254
253
  reportSGM({
255
254
  status: '',
256
255
  text: '渲染本地非blob图片异常',
257
256
  type: 'renderNoBlobImageError',
258
257
  })
259
258
  }
260
259
  }
261
260
  },
262
261
  [src, hasRetryRef.current],
263
262
  )
264
263
 
265
264
  const imageLoad = useCallback(
266
265
  (_src, event) => {
267
266
  setLoadSuccess(true)
268
267
  typeof onLoad === 'function' && onLoad(event, src, props)
269
268
  },
270
269
  [src],
271
270
  )
272
271
 
273
272
  const changeStyleIncludeWidthAndHeightAndBgColor = () => {
274
273
  const changeStyle = {}
275
274
  width && (changeStyle['width'] = width)
276
275
  height && (changeStyle['height'] = height)
277
276
  backgroundColor && (changeStyle['backgroundColor'] = backgroundColor)
278
277
  return changeStyle
279
278
  }
280
279
  useEffect(() => {
281
280
  try {
282
281
  const { mode } = otherOption
283
282
  if (mode && mode === 'heightFix') {
284
283
  className?.split(/\s/)?.forEach((item) => {
285
284
  const userDefinedClass = getRuleBySelector('.' + item)
286
285
  const userDefinedHeight = userDefinedClass?.style?.height
287
286
  if (userDefinedHeight === '' || userDefinedHeight === 'auto') {
288
287
  console.warn(
289
288
  "🚗 ~~ 发现一例用户使用图片组件设置了 mode='heightFix' 并且没有定义一个具体高度:",
290
289
  userDefinedHeight,
291
290
  {
292
291
  code: getSgmCustomCode(`imageUsageCheck`),
293
292
  msg: {
294
293
  userDefinedClass: item,
295
294
  userDefinedHeight,
296
295
  },
297
296
  },
298
297
  )
299
298
  sgmCustomReport({
300
299
  code: getSgmCustomCode(`imageUsageCheck`),
301
300
  msg: {
302
301
  userDefinedClass: item,
303
302
  userDefinedHeight,
304
303
  },
305
304
  })
306
305
  }
307
306
  })
308
307
  }
309
308
  } catch (e) {
310
309
  console.warn('imageUsageCheck error:', e)
311
310
  }
312
311
  setMeasureComplete(true)
313
312
  if (needShowHighVersion) return
314
313
  const latestRes =
315
314
  latestFromNativeMsgStorage[TaroEventType.PAGE_SCROLL] || {}
316
315
  !componentShowStateRef.current && dealPageScrollInfo(latestRes)
317
316
  Taro.eventCenter.on(TaroEventType.PAGE_SCROLL, (res) => {
318
317
  !componentShowStateRef.current && dealPageScrollInfo(res)
319
318
  })
320
319
  }, [])
321
320
 
322
321
  const dealPageScrollInfo = (res) => {
323
322
  const { displayHeight, offSetY } = getNativePageScrollRes(res) || {}
324
323
  if (typeof displayHeight === 'undefined' || typeof offSetY === 'undefined')
325
324
  return
326
325
  if (measureRef.current) {
327
326
  const eleClientRect = measureRef.current.getBoundingClientRect()
328
327
  const getContainerHeightOffSetY = displayHeight * 1.5 + offSetY
329
328
  const eleOffsetTop = Math.ceil(eleClientRect.top)
330
329
  const eleOffsetHeight = Math.ceil(eleClientRect.height)
331
330
  if (!componentShowStateRef.current) {
332
331
  if (getContainerHeightOffSetY > eleOffsetTop) {
333
332
  componentShowStateRef.current = true
334
333
  setComponentShowState(true)
335
334
  }
336
335
  }
337
336
  }
338
337
  }
339
338
  return isH5AndJdShopView &&
340
339
  global?.config?.needImageLazy !== false &&
341
340
  !needShowHighVersion &&
342
341
  !isAppStowShop ? (
343
342
  <View
344
343
  ref={measureRef}
345
344
  className={classNames(
346
345
  imageStyle['d-app-lazy-image'],
347
346
  {
348
347
  [imageStyle['d-lazy-sku-image']]: isSkuImage,
349
348
  },
350
349
  {
351
350
  [imageStyle['d-hide-image-error']]: imageErrState,
352
351
  },
353
352
  {
354
353
  [imageStyle['d-load-completed']]: loadSuccess,
355
354
  },
356
355
  {
357
356
  'd-imag-rendering-crisp-edges':
358
357
  !isVipShop && imagRenderingSet,
359
358
  },
360
359
  'J_html5ImageBg',
361
360
  className,
362
361
  )}
363
362
  style={{
364
363
  ...style,
365
364
  ...changeStyleIncludeWidthAndHeightAndBgColor(),
366
365
  }}
367
366
  {...otherOption}
368
367
  >
369
368
  {(componentShowState || lazyLoad === false) && (
370
369
  <img
371
370
  src={getQualityImage(
372
371
  imgSrc,
373
372
  isVipShop
374
373
  ? NetWorkTypeQuality['perfect']
375
374
  : NetWorkTypeQuality[getNetWorkType],
376
375
  )}
377
376
  onLoad={imageLoad.bind(this, imgSrc)}
378
377
  onError={imageErrorHandle}
379
378
  />
380
379
  )}
381
380
  </View>
382
381
  ) : enableAvifOptimize ? (
383
382
  [
384
383
  measureComplete ? (
385
384
  <Image
386
385
  key={hasRetrySuccess ? 'realImageRetry' : 'realImage'}
387
386
  style={{
388
387
  ...style,
389
388
  ...changeStyleIncludeWidthAndHeightAndBgColor(),
390
389
  }}
391
390
  className={classNames(
392
391
  imageStyle['d-lazy-image'],
393
392
  {
394
393
  [imageStyle['d-lazy-sku-image']]: isSkuImage,
395
394
  },
396
395
  {
397
396
  [imageStyle['d-hide-image-error']]: imageErrState,
398
397
  },
399
398
  {
400
399
  [imageStyle['d-load-completed']]: loadSuccess,
401
400
  },
402
401
  {
403
402
  'd-imag-rendering-crisp-edges': imagRenderingSet,
404
403
  },
405
404
  {
406
405
  [imageStyle["d-no-jd-dog"]]: isVipShop && !isSkuImage,
407
406
  },
408
407
  className,
409
408
  )}
410
409
  src={hasRetrySuccess ? imgSrc : getRequestSrc(imgSrc)}
411
410
  lazyLoad={isChartH5 ? false : lazyLoad}
412
411
  onError={imageErrorHandle}
413
412
  onLoad={imageLoad.bind(this, imgSrc)}
414
413
  {...otherOption}
415
414
  />
416
415
  ) : (
417
416
  <Image
418
417
  key="defaultImage"
419
418
  style={{
420
419
  ...style,
421
420
  ...changeStyleIncludeWidthAndHeightAndBgColor(),
422
421
  }}
423
422
  className={classNames(
424
423
  imageStyle['d-lazy-image'],
425
424
  {
426
425
  [imageStyle['d-lazy-sku-image']]: isSkuImage,
427
426
  },
428
427
  {
429
428
  [imageStyle['d-hide-image-error']]: imageErrState,
430
429
  },
431
430
  {
432
431
  [imageStyle['d-load-completed']]: loadSuccess,
433
432
  },
434
433
  {
435
434
  'd-imag-rendering-crisp-edges': imagRenderingSet,
436
435
  },
437
436
  {
438
437
  [imageStyle["d-no-jd-dog"]]: isVipShop && !isSkuImage,
439
438
  },
440
439
  className,
441
440
  )}
442
441
  src={isSkuImage ? DEFAULT_SKU_SRC : DEFAULT_SRC}
443
442
  />
444
443
  ),
445
444
  loadSuccess ? null : <View key="measureRef" ref={measureRef}></View>,
446
445
  ]
447
446
  ) : (
448
447
  <Image
449
448
  style={{
450
449
  ...style,
451
450
  ...changeStyleIncludeWidthAndHeightAndBgColor(),
452
451
  }}
453
452
  className={classNames(
454
453
  imageStyle['d-lazy-image'],
455
454
  {
456
455
  [imageStyle['d-lazy-sku-image']]: isSkuImage,
457
456
  },
458
457
  {
459
458
  [imageStyle['d-hide-image-error']]: imageErrState,
460
459
  },
461
460
  {
462
461
  [imageStyle['d-load-completed']]: loadSuccess,
463
462
  },
464
463
  {
465
464
  'd-imag-rendering-crisp-edges': imagRenderingSet,
466
465
  },
467
466
  className,
468
467
  )}
469
468
  src={getQualityImage(imgSrc, NetWorkTypeQuality[getNetWorkType])}
470
469
  lazyLoad={isChartH5 ? false : lazyLoad}
471
470
  onError={imageErrorHandle}
472
471
  onLoad={imageLoad.bind(this, imgSrc)}
473
472
  {...otherOption}
474
473
  />
475
474
  )
475
+ import React, { useCallback, useEffect, useRef, useState } from 'react'
476
476
  TaroEventType,
477
477
  const styleSheets = document.styleSheets
478
478
  const internalStyleSheets = []
479
479
  for (let i = 0; i < styleSheets.length; i++) {
480
480
  const sheet = styleSheets[i]
481
481
  const ownerNode = sheet.ownerNode
482
482
  if (ownerNode && ownerNode.nodeName === 'STYLE') {
483
483
  internalStyleSheets.push(sheet)
484
484
  }
485
485
  }
486
486
  for(let i = 0; i < internalStyleSheets.length; i++){
487
487
  try {
488
488
  const sheet = internalStyleSheets[i]
489
489
  const rules = sheet.cssRules || sheet.rules
490
490
  for (const rule of rules) {
491
491
  if (rule?.selectorText?.match(new RegExp(selector + '$'))) {
492
492
  return rule
493
493
  }
494
494
  }
495
495
  } catch (e) {
496
496
  console.warn('因安全限制无法访问样式表:', e)
497
497
  }
498
498
  }
499
499
  return null
500
500
  const {
501
501
  src,
502
502
  lazyLoad,
503
503
  imagRenderingSet,
504
504
  width,
505
505
  height,
506
506
  className,
507
507
  isSkuImage,
508
508
  hideErrorImage,
509
509
  style,
510
510
  backgroundColor,
511
511
  errorSrc,
512
512
  onLoad,
513
513
  onError,
514
514
  ...otherOption
515
515
  } = props
516
516
  getNetWorkType === NetWorkTypeQuality.default &&
517
517
  (getNetWorkType = global.info.sysInfo.netWorkType)
518
518
  const [loadSuccess, setLoadSuccess] = useState(false)
519
519
  const [imageErrState, setImageErrState] = useState(false)
520
520
  const [componentShowState, setComponentShowState] = useState(false)
521
521
  const measureRef = useRef < HTMLElement | null > (null)
522
522
  const [measureComplete, setMeasureComplete] = useState(false)
523
523
  const [imgSrc, setImgSrc] = useState(src)
524
524
  const [hasRetrySuccess, setHasRetrySuccess] = useState(false)
525
525
  const hasRetryRef = useRef(false)
526
526
  const componentShowStateRef = useRef(false)
527
527
  const requestSrcRef = useRef(src)
528
528
  const needShowHighVersion = isH5AndJdShopViewH5Scroll && !(global.info.queryInfo?.downgraded && global.info.queryInfo.downgraded === "true")
529
529
  const enableAvifOptimize = isImageOptimizeEnable()
530
530
  const avifSupport = getAvifSupport()
531
531
  const webpSupport = getWebpSupport()
532
532
 
533
533
 
534
534
  const getRequestSrc = useCallback((src) => {
535
535
  const requestSrc = getQualityImage(
536
536
  imgSrc,
537
537
  { isSkuImage, size: measureRef?.current?.getBoundingClientRect()?.width }
538
538
  )
539
539
  requestSrcRef.current = requestSrc
540
540
  return requestSrc
541
541
  }, [src])
542
542
  const imageErrorRetry = (src) => {
543
543
  return new Promise((resolve, reject) => {
544
544
  if(fetch && window && window.Image){
545
545
  fetch(src)
546
546
  .then(response => {
547
547
  const {ok, status} = response
548
548
  if (ok) {
549
549
  const originUrl = src.replace(/\.(jpe?g|png).*/, '.$1')
550
550
  response.blob().then(blob => {
551
551
  if(URL){
552
552
  const url = URL.createObjectURL(blob)
553
553
  const img = new window.Image()
554
554
  img.src = url;
555
555
  img.onload = () => {
556
556
  reportSGM({status, text: '再次请求并且onload了', type: 'retryAndOnload', requestSrc: src, resolveUrl: url})
557
557
  resolve({
558
558
  ok: true,
559
559
  url
560
560
  })
561
561
  setTimeout(() => {
562
562
  URL.revokeObjectURL(url)
563
563
  }, 2000)
564
564
  };
565
565
  img.onerror = () => {
566
566
  reportSGM({status, text: '图片解析异常', type: 'imageParseError', requestSrc: src})
567
567
  URL.revokeObjectURL(url)
568
568
  resolve({
569
569
  ok: true,
570
570
  url: originUrl
571
571
  })
572
572
  };
573
573
  }else{
574
574
  resolve({
575
575
  ok: true,
576
576
  url: originUrl
577
577
  })
578
578
  }
579
579
  }).catch(error => {
580
580
  resolve({
581
581
  ok: true,
582
582
  url: originUrl
583
583
  })
584
584
  console.error('LazyLoadImage imageErrorRetry() error:', error)
585
585
  });
586
586
  }else {
587
587
  if(status === 404){
588
588
  resolve({
589
589
  ok: false,
590
590
  text: '访问图片不存在',
591
591
  type: 'noSuchUrlImage',
592
592
  })
593
593
  }else{
594
594
  resolve({
595
595
  ok: false,
596
596
  status: status,
597
597
  text: '其它图片问题',
598
598
  type: 'otherImageError',
599
599
  })
600
600
  }
601
601
  }
602
602
  })
603
603
  .catch(error => {
604
604
  resolve({
605
605
  ok: false,
606
606
  text: '网络异常',
607
607
  type: 'networkError',
608
608
  })
609
609
  console.error('LazyLoadImage imageErrorRetry() error:', error)
610
610
  });
611
611
  }else{
612
612
  resolve({
613
613
  ok: false,
614
614
  text: '不支持重试',
615
615
  type: 'notSupportRetry',
616
616
  })
617
617
  }
618
618
  })
619
619
 
620
620
 
621
621
  const reportSGM = ({status, text, type, requestSrc = imgSrc, resolveUrl = ''}) => {
622
622
  const { shopId, venderId } = global.info.queryInfo || {}
623
623
  sgmCustomReport({
624
624
  code: getSgmCustomCode(`${SgmCustomCode.IMAGE_LOAD}_${type}`),
625
625
  msg: {
626
626
  avifSupport,
627
627
  webpSupport,
628
628
  shopId,
629
629
  venderId,
630
630
  originSrc: src,
631
631
  requestSrc,
632
632
  resolveUrl,
633
633
  status,
634
634
  text
635
635
  },
636
636
  })
637
637
  }
638
638
  const imageErrorHandle = useCallback(
639
639
  (e) => {
640
640
  console.log(' ==============> 图片加载错误', e)
641
641
  if (!hasRetryRef.current) {
642
642
  hasRetryRef.current = true
643
643
  if(src){
644
644
  try{
645
645
  imageErrorRetry(requestSrcRef.current).then((result) => {
646
646
  const { status, ok, text, type, url } = result || {}
647
647
  if(ok){
648
648
  setImgSrc(url)
649
649
  setHasRetrySuccess(true)
650
650
  }else{
651
651
  errorSrc && setImgSrc(errorSrc)
652
652
  hideErrorImage && setImageErrState(true)
653
653
  typeof onError === 'function' && onError(e, src, props)
654
654
  reportSGM({status, text, type, requestSrc: requestSrcRef.current})
655
655
  }
656
656
  })
657
657
  }catch(e){
658
658
  console.error('LazyLoadImage imageErrorHandle() error:', e)
659
659
  errorSrc && setImgSrc(errorSrc)
660
660
  hideErrorImage && setImageErrState(true)
661
661
  typeof onError === 'function' && onError(e, src, props)
662
662
  }
663
663
  }
664
664
  }else{
665
665
  reportSGM({status: '', text: '渲染原始图片渲染异常', type: 'renderOriginImageError'})
666
666
  if(imgSrc.includes('blob:')){
667
667
  reportSGM({status: '', text: '渲染本地blob图片异常', type: 'renderBlobImageError'})
668
668
  }else{
669
669
  reportSGM({status: '', text: '渲染本地非blob图片异常', type: 'renderNoBlobImageError'})
670
670
  }
671
671
  }
672
672
  },
673
673
  [src, hasRetryRef.current],
674
674
  )
675
675
 
676
676
 
677
677
  const imageLoad = useCallback(
678
678
  (_src, event) => {
679
679
  setLoadSuccess(true)
680
680
  typeof onLoad === 'function' && onLoad(event, src, props)
681
681
  },
682
682
  [src],
683
683
  )
684
684
 
685
685
  const changeStyleIncludeWidthAndHeightAndBgColor = () => {
686
686
  const changeStyle = {}
687
687
  width && (changeStyle['width'] = width)
688
688
  height && (changeStyle['height'] = height)
689
689
  backgroundColor && (changeStyle['backgroundColor'] = backgroundColor)
690
690
  return changeStyle
691
691
  }
692
692
  useEffect(() => {
693
693
  try{
694
694
  const { mode } = otherOption
695
695
  if(mode && mode === 'heightFix'){
696
696
  className?.split(/\s/)?.forEach(item => {
697
697
  const userDefinedClass = getRuleBySelector('.' + item)
698
698
  const userDefinedHeight = userDefinedClass?.style?.height
699
699
  if(userDefinedHeight === '' || userDefinedHeight === 'auto'){
700
700
  console.warn("🚗 ~~ 发现一例用户使用图片组件设置了 mode='heightFix' 并且没有定义一个具体高度:", userDefinedHeight, {
701
701
  code: getSgmCustomCode(`imageUsageCheck`),
702
702
  msg: {
703
703
  userDefinedClass: item,
704
704
  userDefinedHeight
705
705
  },
706
706
  })
707
707
  sgmCustomReport({
708
708
  code: getSgmCustomCode(`imageUsageCheck`),
709
709
  msg: {
710
710
  userDefinedClass: item,
711
711
  userDefinedHeight
712
712
  },
713
713
  })
714
714
  }
715
715
  })
716
716
  }
717
717
  }catch(e){
718
718
  console.warn('imageUsageCheck error:', e)
719
719
  }
720
720
  setMeasureComplete(true)
721
721
  if (needShowHighVersion) return
722
722
  const latestRes = latestFromNativeMsgStorage[TaroEventType.PAGE_SCROLL] || {}
723
723
  !componentShowStateRef.current && dealPageScrollInfo(latestRes)
724
724
  Taro.eventCenter.on(TaroEventType.PAGE_SCROLL, (res) => {
725
725
  !componentShowStateRef.current && dealPageScrollInfo(res)
726
726
  })
727
727
  }, [])
728
728
 
729
729
  const dealPageScrollInfo = (res) => {
730
730
  const { displayHeight, offSetY } = getNativePageScrollRes(res) || {}
731
731
  if (typeof displayHeight === 'undefined' || typeof offSetY === 'undefined') return
732
732
  if (measureRef.current) {
733
733
  const eleClientRect =
734
734
  measureRef.current.getBoundingClientRect()
735
735
  const getContainerHeightOffSetY =
736
736
  displayHeight * 1.5 + offSetY
737
737
  const eleOffsetTop = Math.ceil(eleClientRect.top)
738
738
  const eleOffsetHeight = Math.ceil(eleClientRect.height)
739
739
  if (!componentShowStateRef.current) {
740
740
  if (getContainerHeightOffSetY > eleOffsetTop) {
741
741
  componentShowStateRef.current = true
742
742
  setComponentShowState(true)
743
743
  }
744
744
  }
745
745
  }
746
746
  }
747
747
  return (
748
748
  isH5AndJdShopView &&
749
749
  global?.config?.needImageLazy !== false &&
750
750
  !needShowHighVersion &&
751
751
  !isAppStowShop ? (
752
752
  <View
753
753
  ref={measureRef}
754
754
  className={classNames(
755
755
  imageStyle["d-app-lazy-image"],
756
756
  {
757
757
  [imageStyle["d-lazy-sku-image"]]: isSkuImage,
758
758
  },
759
759
  {
760
760
  [imageStyle["d-hide-image-error"]]: imageErrState,
761
761
  },
762
762
  {
763
763
  [imageStyle["d-load-completed"]]: loadSuccess,
764
764
  },
765
765
  {
766
766
  "d-imag-rendering-crisp-edges":
767
767
  !global.info.pageInfo.isVipShop && imagRenderingSet,
768
768
  },
769
769
  "J_html5ImageBg",
770
770
  className
771
771
  )}
772
772
  style={{
773
773
  ...style,
774
774
  ...changeStyleIncludeWidthAndHeightAndBgColor(),
775
775
  }}
776
776
  {...otherOption}
777
777
  >
778
778
  {(componentShowState || lazyLoad === false) && (
779
779
  <img
780
780
  src={getQualityImage(
781
781
  imgSrc,
782
782
  global.info.pageInfo.isVipShop
783
783
  ? NetWorkTypeQuality["perfect"]
784
784
  : NetWorkTypeQuality[getNetWorkType]
785
785
  )}
786
786
  onLoad={imageLoad.bind(this, imgSrc)}
787
787
  onError={imageErrorHandle}
788
788
  />
789
789
  )}
790
790
  </View>
791
791
  ) : enableAvifOptimize ? (
792
792
  [
793
793
  measureComplete ? (
794
794
  <Image
795
795
  key={hasRetrySuccess? "realImageRetry": "realImage"}
796
796
  style={{
797
797
  ...style,
798
798
  ...changeStyleIncludeWidthAndHeightAndBgColor(),
799
799
  }}
800
800
  className={classNames(
801
801
  imageStyle["d-lazy-image"],
802
802
  {
803
803
  [imageStyle["d-lazy-sku-image"]]: isSkuImage,
804
804
  },
805
805
  {
806
806
  [imageStyle["d-hide-image-error"]]: imageErrState,
807
807
  },
808
808
  {
809
809
  [imageStyle["d-load-completed"]]: loadSuccess,
810
810
  },
811
811
  {
812
812
  "d-imag-rendering-crisp-edges": imagRenderingSet,
813
813
  },
814
814
  className
815
815
  )}
816
816
  src={hasRetrySuccess? imgSrc: getRequestSrc(imgSrc)}
817
817
  lazyLoad={isChartH5 ? false : lazyLoad}
818
818
  onError={imageErrorHandle}
819
819
  onLoad={imageLoad.bind(this, imgSrc)}
820
820
  {...otherOption}
821
821
  />
822
822
  ) : (
823
823
  <Image
824
824
  key="defaultImage"
825
825
  style={{
826
826
  ...style,
827
827
  ...changeStyleIncludeWidthAndHeightAndBgColor(),
828
828
  }}
829
829
  className={classNames(
830
830
  imageStyle["d-lazy-image"],
831
831
  {
832
832
  [imageStyle["d-lazy-sku-image"]]: isSkuImage,
833
833
  },
834
834
  {
835
835
  [imageStyle["d-hide-image-error"]]: imageErrState,
836
836
  },
837
837
  {
838
838
  [imageStyle["d-load-completed"]]: loadSuccess,
839
839
  },
840
840
  {
841
841
  "d-imag-rendering-crisp-edges": imagRenderingSet,
842
842
  },
843
843
  className
844
844
  )}
845
845
  src={isSkuImage ? DEFAULT_SKU_SRC : DEFAULT_SRC}
846
846
  />
847
847
  ),
848
848
  loadSuccess ? null : <View key="measureRef" ref={measureRef}></View>,
849
849
  ]
850
850
  ) : (
851
851
  <Image
852
852
  style={{
853
853
  ...style,
854
854
  ...changeStyleIncludeWidthAndHeightAndBgColor(),
855
855
  }}
856
856
  className={classNames(
857
857
  imageStyle["d-lazy-image"],
858
858
  {
859
859
  [imageStyle["d-lazy-sku-image"]]: isSkuImage,
860
860
  },
861
861
  {
862
862
  [imageStyle["d-hide-image-error"]]: imageErrState,
863
863
  },
864
864
  {
865
865
  [imageStyle["d-load-completed"]]: loadSuccess,
866
866
  },
867
867
  {
868
868
  "d-imag-rendering-crisp-edges": imagRenderingSet,
869
869
  },
870
870
  className
871
871
  )}
872
872
  src={getQualityImage(imgSrc, NetWorkTypeQuality[getNetWorkType])}
873
873
  lazyLoad={isChartH5 ? false : lazyLoad}
874
874
  onError={imageErrorHandle}
875
875
  onLoad={imageLoad.bind(this, imgSrc)}
876
876
  {...otherOption}
877
877
  />
878
878
  )
879
879
  )
880
880
  lazyLoad: true,
881
881
  isSkuImage: false,
882
882
  hideErrorImage: false,
883
883
  imagRenderingSet: true,
884
884
  src: null,
885
885
  style: null,
886
886
  width: null,
887
887
  height: null,
888
888
  backgroundColor: null,
889
889
  className: null,
890
890
  errorSrc: null,
891
891
  onLoad: null,
892
892
  onError: null,