@onekeyfe/react-native-image 3.0.156 → 3.0.157

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 (36) hide show
  1. package/android/src/main/java/com/margelo/nitro/onekeyimage/OneKeyImage.kt +12 -0
  2. package/ios/OneKeyImage.swift +83 -14
  3. package/ios/OneKeyImageRequestContext.swift +38 -0
  4. package/ios/tests/OneKeyImageInfrastructureTests.swift +85 -0
  5. package/lib/module/index.js +3 -1
  6. package/lib/nitrogen/generated/android/c++/JHybridOneKeyImageSpec.cpp +9 -0
  7. package/lib/nitrogen/generated/android/c++/JHybridOneKeyImageSpec.hpp +2 -0
  8. package/lib/nitrogen/generated/android/c++/views/JHybridOneKeyImageStateUpdater.cpp +5 -0
  9. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/onekeyimage/HybridOneKeyImageSpec.kt +6 -0
  10. package/lib/nitrogen/generated/ios/c++/HybridOneKeyImageSpecSwift.hpp +7 -0
  11. package/lib/nitrogen/generated/ios/c++/views/HybridOneKeyImageComponent.mm +6 -0
  12. package/lib/nitrogen/generated/ios/swift/HybridOneKeyImageSpec.swift +1 -0
  13. package/lib/nitrogen/generated/ios/swift/HybridOneKeyImageSpec_cxx.swift +24 -0
  14. package/lib/nitrogen/generated/shared/c++/HybridOneKeyImageSpec.cpp +2 -0
  15. package/lib/nitrogen/generated/shared/c++/HybridOneKeyImageSpec.hpp +2 -0
  16. package/lib/nitrogen/generated/shared/c++/views/HybridOneKeyImageComponent.cpp +2 -0
  17. package/lib/nitrogen/generated/shared/c++/views/HybridOneKeyImageComponent.hpp +3 -0
  18. package/lib/nitrogen/generated/shared/json/OneKeyImageConfig.json +1 -0
  19. package/lib/typescript/src/OneKeyImage.nitro.d.ts +6 -0
  20. package/lib/typescript/src/index.d.ts +1 -1
  21. package/nitrogen/generated/android/c++/JHybridOneKeyImageSpec.cpp +9 -0
  22. package/nitrogen/generated/android/c++/JHybridOneKeyImageSpec.hpp +2 -0
  23. package/nitrogen/generated/android/c++/views/JHybridOneKeyImageStateUpdater.cpp +5 -0
  24. package/nitrogen/generated/android/kotlin/com/margelo/nitro/onekeyimage/HybridOneKeyImageSpec.kt +6 -0
  25. package/nitrogen/generated/ios/c++/HybridOneKeyImageSpecSwift.hpp +7 -0
  26. package/nitrogen/generated/ios/c++/views/HybridOneKeyImageComponent.mm +6 -0
  27. package/nitrogen/generated/ios/swift/HybridOneKeyImageSpec.swift +1 -0
  28. package/nitrogen/generated/ios/swift/HybridOneKeyImageSpec_cxx.swift +24 -0
  29. package/nitrogen/generated/shared/c++/HybridOneKeyImageSpec.cpp +2 -0
  30. package/nitrogen/generated/shared/c++/HybridOneKeyImageSpec.hpp +2 -0
  31. package/nitrogen/generated/shared/c++/views/HybridOneKeyImageComponent.cpp +2 -0
  32. package/nitrogen/generated/shared/c++/views/HybridOneKeyImageComponent.hpp +3 -0
  33. package/nitrogen/generated/shared/json/OneKeyImageConfig.json +1 -0
  34. package/package.json +2 -2
  35. package/src/OneKeyImage.nitro.ts +6 -0
  36. package/src/index.tsx +3 -1
@@ -180,6 +180,7 @@ internal fun oneKeyImageRequestSignature(
180
180
  height: Int,
181
181
  density: Float,
182
182
  resizeWidth: Double? = null,
183
+ resizeHeight: Double? = null,
183
184
  ): String = listOf(
184
185
  rawUrl,
185
186
  sourceHeadersJson.orEmpty(),
@@ -190,6 +191,7 @@ internal fun oneKeyImageRequestSignature(
190
191
  overscan.toString(),
191
192
  round.toString(),
192
193
  resizeWidth.toString(),
194
+ resizeHeight.toString(),
193
195
  width.toString(),
194
196
  height.toString(),
195
197
  density.toString(),
@@ -304,6 +306,14 @@ class HybridOneKeyImage(private val context: ThemedReactContext) :
304
306
  field = value
305
307
  requestIdentityChanged()
306
308
  }
309
+ // Layout hint pair with resizeWidth; only the iOS pre-layout memory probe
310
+ // consumes it today, Android keys the request on the measured view size.
311
+ override var resizeHeight: Double? = null
312
+ set(value) {
313
+ if (field == value) return
314
+ field = value
315
+ requestIdentityChanged()
316
+ }
307
317
  override var loadingStrategy: OneKeyImageLoadingStrategy? = OneKeyImageLoadingStrategy.STATIC
308
318
  set(value) {
309
319
  field = value
@@ -403,6 +413,7 @@ class HybridOneKeyImage(private val context: ThemedReactContext) :
403
413
  optimizeTos = true
404
414
  round = false
405
415
  resizeWidth = null
416
+ resizeHeight = null
406
417
  overscan = 1.1
407
418
  loadingStrategy = OneKeyImageLoadingStrategy.STATIC
408
419
  placeholderColor = null
@@ -477,6 +488,7 @@ class HybridOneKeyImage(private val context: ThemedReactContext) :
477
488
  height = hostView.height,
478
489
  density = hostView.resources.displayMetrics.density,
479
490
  resizeWidth = resizeWidth,
491
+ resizeHeight = resizeHeight,
480
492
  )
481
493
  if (!force && signature == lastSignature) return
482
494
  lastSignature = signature
@@ -150,6 +150,11 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
150
150
  if !Self.equalOptionalDouble(resizeWidth, oldValue) { identityDidChange() }
151
151
  }
152
152
  }
153
+ var resizeHeight: Double? {
154
+ didSet {
155
+ if !Self.equalOptionalDouble(resizeHeight, oldValue) { identityDidChange() }
156
+ }
157
+ }
153
158
  var overscan: Double? = 1.1 {
154
159
  didSet {
155
160
  if !Self.equalOptionalDouble(overscan, oldValue) { identityDidChange() }
@@ -260,7 +265,14 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
260
265
  guard !hostView.bounds.isEmpty else {
261
266
  cancelCurrentRequest(invalidateGeneration: true)
262
267
  lastRequestSignature = nil
263
- showLoading(requestIsActive: false, letLibraryStartIndicator: false)
268
+ // A memory-cached image shown from `identityDidChange` before layout
269
+ // stays up; layout re-runs this load with real bounds and confirms it.
270
+ if !Self.shouldPreserveDisplayedImage(
271
+ isShowingImage: displayState == .image,
272
+ hasImage: hostView.image != nil
273
+ ) {
274
+ showLoading(requestIsActive: false, letLibraryStartIndicator: false)
275
+ }
264
276
  return
265
277
  }
266
278
  guard let rawString = sourceUri, !rawString.isEmpty else {
@@ -280,6 +292,7 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
280
292
  contentFit?.stringValue ?? "cover",
281
293
  String(optimizeTos ?? true),
282
294
  resizeWidth.map(String.init(describing:)) ?? "",
295
+ resizeHeight.map(String.init(describing:)) ?? "",
283
296
  String(overscan ?? 1.1),
284
297
  String(Int(hostView.bounds.width.rounded())),
285
298
  String(Int(hostView.bounds.height.rounded())),
@@ -295,7 +308,20 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
295
308
  onLoadStart?()
296
309
  guard Self.isCurrentRequestGeneration(generation, current: requestGeneration) else { return }
297
310
  if showMemoryCachedImageIfAvailable(requestIsActive: true) { return }
298
- showLoading(requestIsActive: true, letLibraryStartIndicator: true)
311
+ // The pre-layout probe may have shown this identity from another thumbnail
312
+ // key (a preload's, or an earlier layout size). Keep it on screen as the
313
+ // placeholder while the exact rendition loads: blanking to a skeleton and
314
+ // redrawing is worse than the skeleton it replaced.
315
+ let preservedImage =
316
+ Self.shouldPreserveDisplayedImage(
317
+ isShowingImage: displayState == .image,
318
+ hasImage: hostView.image != nil
319
+ ) ? hostView.image : nil
320
+ showLoading(
321
+ requestIsActive: true,
322
+ letLibraryStartIndicator: true,
323
+ preservedImage: preservedImage
324
+ )
299
325
 
300
326
  if let violation = OneKeyImageSafetyPolicy.preflight(source: rawString) {
301
327
  finishWithError(violation, generation: generation)
@@ -327,7 +353,8 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
327
353
  url: requestURL,
328
354
  rawURL: rawURL,
329
355
  generation: generation,
330
- mayFallbackToRaw: requestURL != rawURL
356
+ mayFallbackToRaw: requestURL != rawURL,
357
+ placeholderImage: preservedImage
331
358
  )
332
359
  }
333
360
 
@@ -335,7 +362,8 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
335
362
  url: URL,
336
363
  rawURL: URL,
337
364
  generation: UInt64,
338
- mayFallbackToRaw: Bool
365
+ mayFallbackToRaw: Bool,
366
+ placeholderImage: UIImage? = nil
339
367
  ) {
340
368
  guard Self.isCurrentRequestGeneration(generation, current: requestGeneration) else { return }
341
369
  let rawScreenScale: CGFloat = hostView.window?.screen.scale ?? UIScreen.main.scale
@@ -363,7 +391,9 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
363
391
  )
364
392
  hostView.sd_internalSetImage(
365
393
  with: url,
366
- placeholderImage: nil,
394
+ // SDWebImage resets the image view when it starts a load; hand it the
395
+ // preserved image so the view keeps showing it until the load lands.
396
+ placeholderImage: placeholderImage,
367
397
  options: OneKeyImageRequestContext.renderOptions,
368
398
  context: context,
369
399
  setImageBlock: { [weak self] image, _, _, _ in
@@ -552,18 +582,40 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
552
582
 
553
583
  private func showLoading(
554
584
  requestIsActive: Bool,
555
- letLibraryStartIndicator: Bool
585
+ letLibraryStartIndicator: Bool,
586
+ preservedImage: UIImage? = nil
556
587
  ) {
557
588
  displayState = .loading
558
589
  requestActive = requestIsActive
559
590
  resetImageTransition()
560
- hostView.image = nil
561
591
  fallbackLayer.isHidden = true
592
+ if let preservedImage {
593
+ // Same identity, different thumbnail key: the image already on screen
594
+ // stands in for the placeholder, so no blank frame and no indicator.
595
+ hostView.image = preservedImage
596
+ skeletonIndicator.stopAnimatingIndicator()
597
+ hostView.backgroundColor = .clear
598
+ return
599
+ }
600
+ hostView.image = nil
562
601
  applyLoadingAppearance(letLibraryStartIndicator: letLibraryStartIndicator)
563
602
  }
564
603
 
604
+ /// Whether the image currently on screen should stay up while a load for the
605
+ /// SAME identity runs (bounds not laid out yet, or the laid-out request key
606
+ /// differs from the one the pre-layout probe hit). Pure for testability.
607
+ static func shouldPreserveDisplayedImage(isShowingImage: Bool, hasImage: Bool) -> Bool {
608
+ isShowingImage && hasImage
609
+ }
610
+
565
611
  private func showMemoryCachedImageIfAvailable(requestIsActive: Bool) -> Bool {
566
- guard cachePolicy == .memory || cachePolicy == .memoryDisk,
612
+ // JS leaves `cachePolicy` unset for the common case and Fabric then hands
613
+ // Nitro a nil, which the request path already treats as memory-disk; the
614
+ // probe must agree, otherwise a nil policy skips the memory lookup entirely
615
+ // and every mount pays the async pipeline round trip (an icon skeleton
616
+ // frame) for an image that is already decoded in memory.
617
+ let effectivePolicy = cachePolicy ?? .memoryDisk
618
+ guard effectivePolicy == .memory || effectivePolicy == .memoryDisk,
567
619
  let sourceUri,
568
620
  let rawURL = URL(string: sourceUri) else {
569
621
  return false
@@ -583,12 +635,21 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
583
635
  hasCustomIdentity: hasCustomIdentity
584
636
  )
585
637
  : rawURL
586
- let thumbnailPixelSize = OneKeyImageDecodeSizing.thumbnailPixelSize(
587
- viewSize: hostView.bounds.size,
588
- scale: screenScale,
589
- contentFit: contentFit ?? .cover
590
- )
591
- func memoryCachedImage(for url: URL) -> UIImage? {
638
+ // The thumbnail size is part of the cache key. Laid out, it is this view's
639
+ // own request key; before layout it comes from the resize hints, under
640
+ // this view's contentFit and under `.cover` (a preload's key). With no
641
+ // bounds and no hint the un-thumbnailed key is the only thing to try.
642
+ let thumbnailCandidates: [CGSize?] = {
643
+ let sizes = OneKeyImageDecodeSizing.probeThumbnailPixelSizes(
644
+ bounds: hostView.bounds.size,
645
+ resizeWidth: resizeWidth,
646
+ resizeHeight: resizeHeight,
647
+ scale: screenScale,
648
+ contentFit: contentFit ?? .cover
649
+ )
650
+ return sizes.isEmpty ? [nil] : sizes
651
+ }()
652
+ func memoryCachedImage(for url: URL, thumbnailPixelSize: CGSize?) -> UIImage? {
592
653
  let context = OneKeyImageRequestContext.make(
593
654
  headersJson: sourceHeadersJson,
594
655
  cachePolicy: cachePolicy ?? .memoryDisk,
@@ -603,6 +664,14 @@ final class HybridOneKeyImage: HybridOneKeyImageSpec, RecyclableView {
603
664
  }
604
665
  return cache.imageFromMemoryCache(forKey: key)
605
666
  }
667
+ func memoryCachedImage(for url: URL) -> UIImage? {
668
+ for thumbnailPixelSize in thumbnailCandidates {
669
+ if let image = memoryCachedImage(for: url, thumbnailPixelSize: thumbnailPixelSize) {
670
+ return image
671
+ }
672
+ }
673
+ return nil
674
+ }
606
675
  guard let image = memoryCachedImage(for: requestURL)
607
676
  ?? (requestURL == rawURL ? nil : memoryCachedImage(for: rawURL)) else {
608
677
  return false
@@ -610,6 +610,44 @@ enum OneKeyImageDecodeSizing {
610
610
  }
611
611
  }
612
612
 
613
+ /// Decode-thumbnail sizes worth probing the memory cache with, most specific
614
+ /// first. The thumbnail size is part of the SDWebImage cache key, so a probe
615
+ /// only hits when it reproduces the key some earlier load stored under.
616
+ ///
617
+ /// - Laid out: exactly the size this view's own request uses (`bounds` +
618
+ /// `contentFit`), nothing else.
619
+ /// - Before layout the bounds are empty, but the JS side already knows the
620
+ /// display size through the `resizeWidth` / `resizeHeight` hints (the same
621
+ /// fields a preload takes). Two keys can hold the image then: the one the
622
+ /// laid-out request will ask for (hint + this view's `contentFit`) and the
623
+ /// one a preload stored (hint + `.cover`, see `HybridOneKeyImageCache`).
624
+ /// They coincide for a square hint or `.cover`; otherwise both are probed.
625
+ /// - No bounds and no usable hint: nothing to probe with.
626
+ static func probeThumbnailPixelSizes(
627
+ bounds: CGSize,
628
+ resizeWidth: Double?,
629
+ resizeHeight: Double?,
630
+ scale: CGFloat,
631
+ contentFit: OneKeyImageContentFit
632
+ ) -> [CGSize] {
633
+ if bounds.width.isFinite, bounds.height.isFinite, bounds.width > 0, bounds.height > 0 {
634
+ return thumbnailPixelSize(viewSize: bounds, scale: scale, contentFit: contentFit)
635
+ .map { [$0] } ?? []
636
+ }
637
+ guard let hint = logicalViewSize(width: resizeWidth, height: resizeHeight) else {
638
+ return []
639
+ }
640
+ var sizes: [CGSize] = []
641
+ for fit in [contentFit, .cover] {
642
+ if let size = thumbnailPixelSize(viewSize: hint, scale: scale, contentFit: fit),
643
+ !sizes.contains(size)
644
+ {
645
+ sizes.append(size)
646
+ }
647
+ }
648
+ return sizes
649
+ }
650
+
613
651
  static func thumbnailPixelSize(
614
652
  viewSize: CGSize,
615
653
  scale: CGFloat,
@@ -310,6 +310,91 @@ final class OneKeyImageInfrastructureTests: XCTestCase {
310
310
  )
311
311
  }
312
312
 
313
+ // The pre-layout memory probe is only useful if it reproduces a key some
314
+ // earlier load stored under. These pin the probe against the two real key
315
+ // producers: the laid-out render request (bounds + contentFit) and the
316
+ // preload (logicalViewSize(resizeWidth, resizeHeight) + .cover).
317
+ private func renderKey(bounds: CGSize, fit: OneKeyImageContentFit) throws -> CGSize {
318
+ try XCTUnwrap(
319
+ OneKeyImageDecodeSizing.thumbnailPixelSize(viewSize: bounds, scale: 3, contentFit: fit)
320
+ )
321
+ }
322
+
323
+ private func preloadKey(width: Double?, height: Double?) throws -> CGSize {
324
+ try renderKey(
325
+ bounds: try XCTUnwrap(OneKeyImageDecodeSizing.logicalViewSize(width: width, height: height)),
326
+ fit: .cover
327
+ )
328
+ }
329
+
330
+ func testLaidOutProbeUsesExactlyTheRenderRequestKey() throws {
331
+ let bounds = CGSize(width: 40, height: 64)
332
+ for fit in [OneKeyImageContentFit.cover, .contain, .fill, .center] {
333
+ XCTAssertEqual(
334
+ OneKeyImageDecodeSizing.probeThumbnailPixelSizes(
335
+ bounds: bounds, resizeWidth: 32, resizeHeight: 48, scale: 3, contentFit: fit
336
+ ),
337
+ [try renderKey(bounds: bounds, fit: fit)],
338
+ "\(fit)"
339
+ )
340
+ }
341
+ }
342
+
343
+ func testPreLayoutSquareHintMatchesPreloadAndRenderKeys() throws {
344
+ // A token icon: resizeWidth only, laid out square, cover. One key, shared
345
+ // by the preload, the laid-out request and the probe.
346
+ let sizes = OneKeyImageDecodeSizing.probeThumbnailPixelSizes(
347
+ bounds: .zero, resizeWidth: 40, resizeHeight: nil, scale: 3, contentFit: .cover
348
+ )
349
+ XCTAssertEqual(sizes, [CGSize(width: 120, height: 120)])
350
+ XCTAssertEqual(sizes, [try preloadKey(width: 40, height: nil)])
351
+ XCTAssertEqual(sizes, [try renderKey(bounds: CGSize(width: 40, height: 40), fit: .cover)])
352
+ }
353
+
354
+ func testPreLayoutRectangularHintProbesRenderAndPreloadKeys() throws {
355
+ // The README preload shape (48x64 @3) under a non-cover view: the laid-out
356
+ // request key comes first, the preload's cover key second, no duplicates.
357
+ let sizes = OneKeyImageDecodeSizing.probeThumbnailPixelSizes(
358
+ bounds: .zero, resizeWidth: 48, resizeHeight: 64, scale: 3, contentFit: .contain
359
+ )
360
+ XCTAssertEqual(
361
+ sizes,
362
+ [
363
+ try renderKey(bounds: CGSize(width: 48, height: 64), fit: .contain),
364
+ try preloadKey(width: 48, height: 64),
365
+ ]
366
+ )
367
+ XCTAssertEqual(sizes, [CGSize(width: 144, height: 192), CGSize(width: 192, height: 192)])
368
+ // Under cover both collapse to the preload key.
369
+ XCTAssertEqual(
370
+ OneKeyImageDecodeSizing.probeThumbnailPixelSizes(
371
+ bounds: .zero, resizeWidth: 48, resizeHeight: 64, scale: 3, contentFit: .cover
372
+ ),
373
+ [try preloadKey(width: 48, height: 64)]
374
+ )
375
+ }
376
+
377
+ func testPreLayoutProbeWithoutHintHasNothingToTry() {
378
+ XCTAssertEqual(
379
+ OneKeyImageDecodeSizing.probeThumbnailPixelSizes(
380
+ bounds: .zero, resizeWidth: nil, resizeHeight: nil, scale: 3, contentFit: .cover
381
+ ),
382
+ []
383
+ )
384
+ XCTAssertEqual(
385
+ OneKeyImageDecodeSizing.probeThumbnailPixelSizes(
386
+ bounds: .zero, resizeWidth: 0, resizeHeight: -1, scale: 3, contentFit: .cover
387
+ ),
388
+ []
389
+ )
390
+ }
391
+
392
+ func testDisplayedImageIsPreservedOnlyWhileShowingOne() {
393
+ XCTAssertTrue(HybridOneKeyImage.shouldPreserveDisplayedImage(isShowingImage: true, hasImage: true))
394
+ XCTAssertFalse(HybridOneKeyImage.shouldPreserveDisplayedImage(isShowingImage: true, hasImage: false))
395
+ XCTAssertFalse(HybridOneKeyImage.shouldPreserveDisplayedImage(isShowingImage: false, hasImage: true))
396
+ }
397
+
313
398
  func testNoSizePreloadUsesCappedDecodeTarget() {
314
399
  XCTAssertEqual(HybridOneKeyImageCache.maximumConcurrentPreloads, 4)
315
400
  XCTAssertEqual(
@@ -46,6 +46,7 @@ export function OneKeyImage({
46
46
  optimizeTos = true,
47
47
  round = false,
48
48
  resizeWidth,
49
+ resizeHeight,
49
50
  overscan = 1.1,
50
51
  loadingStrategy = OneKeyImageLoadingStrategy.STATIC,
51
52
  placeholderColor,
@@ -60,7 +61,7 @@ export function OneKeyImage({
60
61
  }) {
61
62
  const normalized = useMemo(() => normalizeSource(source), [source]);
62
63
  const resolvedCachePolicy = cachePolicy ?? normalized?.cachePolicy ?? OneKeyImageCachePolicy.MEMORY_DISK;
63
- const identity = `${normalized?.uri ?? ''}|${JSON.stringify(normalized?.headers ?? {})}|${resolvedCachePolicy}|${recyclingKey ?? ''}|${contentFit}|${optimizeTos ? '1' : '0'}|${resizeWidth ?? ''}|${overscan}`;
64
+ const identity = `${normalized?.uri ?? ''}|${JSON.stringify(normalized?.headers ?? {})}|${resolvedCachePolicy}|${recyclingKey ?? ''}|${contentFit}|${optimizeTos ? '1' : '0'}|${resizeWidth ?? ''}|${resizeHeight ?? ''}|${overscan}`;
64
65
  const hasSource = normalized != null;
65
66
  const hasOverlay = placeholder != null || fallback != null;
66
67
  const [loadState, setLoadState] = useState({
@@ -215,6 +216,7 @@ export function OneKeyImage({
215
216
  optimizeTos,
216
217
  round,
217
218
  resizeWidth,
219
+ resizeHeight,
218
220
  overscan,
219
221
  loadingStrategy: placeholder == null ? loadingStrategy : OneKeyImageLoadingStrategy.NONE,
220
222
  placeholderColor
@@ -156,6 +156,15 @@ namespace margelo::nitro::onekeyimage {
156
156
  static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* resizeWidth */)>("setResizeWidth");
157
157
  method(_javaPart, resizeWidth.has_value() ? jni::JDouble::valueOf(resizeWidth.value()) : nullptr);
158
158
  }
159
+ std::optional<double> JHybridOneKeyImageSpec::getResizeHeight() {
160
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getResizeHeight");
161
+ auto __result = method(_javaPart);
162
+ return __result != nullptr ? std::make_optional(__result->value()) : std::nullopt;
163
+ }
164
+ void JHybridOneKeyImageSpec::setResizeHeight(std::optional<double> resizeHeight) {
165
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* resizeHeight */)>("setResizeHeight");
166
+ method(_javaPart, resizeHeight.has_value() ? jni::JDouble::valueOf(resizeHeight.value()) : nullptr);
167
+ }
159
168
  std::optional<double> JHybridOneKeyImageSpec::getOverscan() {
160
169
  static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getOverscan");
161
170
  auto __result = method(_javaPart);
@@ -70,6 +70,8 @@ namespace margelo::nitro::onekeyimage {
70
70
  void setRound(std::optional<bool> round) override;
71
71
  std::optional<double> getResizeWidth() override;
72
72
  void setResizeWidth(std::optional<double> resizeWidth) override;
73
+ std::optional<double> getResizeHeight() override;
74
+ void setResizeHeight(std::optional<double> resizeHeight) override;
73
75
  std::optional<double> getOverscan() override;
74
76
  void setOverscan(std::optional<double> overscan) override;
75
77
  std::optional<OneKeyImageLoadingStrategy> getLoadingStrategy() override;
@@ -103,6 +103,11 @@ void JHybridOneKeyImageStateUpdater::updateViewProps(jni::alias_ref<jni::JClass>
103
103
  : !newProps->resizeWidth.hasSameValue(oldProps->resizeWidth)) {
104
104
  hybridView->setResizeWidth(newProps->resizeWidth.get());
105
105
  }
106
+ if (oldProps == nullptr
107
+ ? newProps->resizeHeight.isProvided()
108
+ : !newProps->resizeHeight.hasSameValue(oldProps->resizeHeight)) {
109
+ hybridView->setResizeHeight(newProps->resizeHeight.get());
110
+ }
106
111
  if (oldProps == nullptr
107
112
  ? newProps->overscan.isProvided()
108
113
  : !newProps->overscan.hasSameValue(oldProps->overscan)) {
@@ -87,6 +87,12 @@ abstract class HybridOneKeyImageSpec: HybridView() {
87
87
  @set:Keep
88
88
  abstract var resizeWidth: Double?
89
89
 
90
+ @get:DoNotStrip
91
+ @get:Keep
92
+ @set:DoNotStrip
93
+ @set:Keep
94
+ abstract var resizeHeight: Double?
95
+
90
96
  @get:DoNotStrip
91
97
  @get:Keep
92
98
  @set:DoNotStrip
@@ -148,6 +148,13 @@ namespace margelo::nitro::onekeyimage {
148
148
  inline void setResizeWidth(std::optional<double> resizeWidth) noexcept override {
149
149
  _swiftPart.setResizeWidth(resizeWidth);
150
150
  }
151
+ inline std::optional<double> getResizeHeight() noexcept override {
152
+ auto __result = _swiftPart.getResizeHeight();
153
+ return __result;
154
+ }
155
+ inline void setResizeHeight(std::optional<double> resizeHeight) noexcept override {
156
+ _swiftPart.setResizeHeight(resizeHeight);
157
+ }
151
158
  inline std::optional<double> getOverscan() noexcept override {
152
159
  auto __result = _swiftPart.getOverscan();
153
160
  return __result;
@@ -158,6 +158,12 @@ using namespace margelo::nitro::onekeyimage::views;
158
158
  : !newViewProps.resizeWidth.hasSameValue(oldViewProps->resizeWidth)) {
159
159
  swiftPart.setResizeWidth(newViewProps.resizeWidth.get());
160
160
  }
161
+ // resizeHeight: optional
162
+ if (oldViewProps == nullptr
163
+ ? newViewProps.resizeHeight.isProvided()
164
+ : !newViewProps.resizeHeight.hasSameValue(oldViewProps->resizeHeight)) {
165
+ swiftPart.setResizeHeight(newViewProps.resizeHeight.get());
166
+ }
161
167
  // overscan: optional
162
168
  if (oldViewProps == nullptr
163
169
  ? newViewProps.overscan.isProvided()
@@ -20,6 +20,7 @@ public protocol HybridOneKeyImageSpec_protocol: HybridObject, HybridView {
20
20
  var optimizeTos: Bool? { get set }
21
21
  var round: Bool? { get set }
22
22
  var resizeWidth: Double? { get set }
23
+ var resizeHeight: Double? { get set }
23
24
  var overscan: Double? { get set }
24
25
  var loadingStrategy: OneKeyImageLoadingStrategy? { get set }
25
26
  var placeholderColor: String? { get set }
@@ -340,6 +340,30 @@ open class HybridOneKeyImageSpec_cxx {
340
340
  }
341
341
  }
342
342
 
343
+ public final var resizeHeight: bridge.std__optional_double_ {
344
+ @inline(__always)
345
+ get {
346
+ return { () -> bridge.std__optional_double_ in
347
+ if let __unwrappedValue = self.__implementation.resizeHeight {
348
+ return bridge.create_std__optional_double_(__unwrappedValue)
349
+ } else {
350
+ return .init()
351
+ }
352
+ }()
353
+ }
354
+ @inline(__always)
355
+ set {
356
+ self.__implementation.resizeHeight = { () -> Double? in
357
+ if bridge.has_value_std__optional_double_(newValue) {
358
+ let __unwrapped = bridge.get_std__optional_double_(newValue)
359
+ return __unwrapped
360
+ } else {
361
+ return nil
362
+ }
363
+ }()
364
+ }
365
+ }
366
+
343
367
  public final var overscan: bridge.std__optional_double_ {
344
368
  @inline(__always)
345
369
  get {
@@ -34,6 +34,8 @@ namespace margelo::nitro::onekeyimage {
34
34
  prototype.registerHybridSetter("round", &HybridOneKeyImageSpec::setRound);
35
35
  prototype.registerHybridGetter("resizeWidth", &HybridOneKeyImageSpec::getResizeWidth);
36
36
  prototype.registerHybridSetter("resizeWidth", &HybridOneKeyImageSpec::setResizeWidth);
37
+ prototype.registerHybridGetter("resizeHeight", &HybridOneKeyImageSpec::getResizeHeight);
38
+ prototype.registerHybridSetter("resizeHeight", &HybridOneKeyImageSpec::setResizeHeight);
37
39
  prototype.registerHybridGetter("overscan", &HybridOneKeyImageSpec::getOverscan);
38
40
  prototype.registerHybridSetter("overscan", &HybridOneKeyImageSpec::setOverscan);
39
41
  prototype.registerHybridGetter("loadingStrategy", &HybridOneKeyImageSpec::getLoadingStrategy);
@@ -80,6 +80,8 @@ namespace margelo::nitro::onekeyimage {
80
80
  virtual void setRound(std::optional<bool> round) = 0;
81
81
  virtual std::optional<double> getResizeWidth() = 0;
82
82
  virtual void setResizeWidth(std::optional<double> resizeWidth) = 0;
83
+ virtual std::optional<double> getResizeHeight() = 0;
84
+ virtual void setResizeHeight(std::optional<double> resizeHeight) = 0;
83
85
  virtual std::optional<double> getOverscan() = 0;
84
86
  virtual void setOverscan(std::optional<double> overscan) = 0;
85
87
  virtual std::optional<OneKeyImageLoadingStrategy> getLoadingStrategy() = 0;
@@ -30,6 +30,7 @@ namespace margelo::nitro::onekeyimage::views {
30
30
  optimizeTos(nitro::ReactProp<std::optional<bool>>::fromRawValue("OneKeyImage", "optimizeTos", rawProps, sourceProps.optimizeTos)),
31
31
  round(nitro::ReactProp<std::optional<bool>>::fromRawValue("OneKeyImage", "round", rawProps, sourceProps.round)),
32
32
  resizeWidth(nitro::ReactProp<std::optional<double>>::fromRawValue("OneKeyImage", "resizeWidth", rawProps, sourceProps.resizeWidth)),
33
+ resizeHeight(nitro::ReactProp<std::optional<double>>::fromRawValue("OneKeyImage", "resizeHeight", rawProps, sourceProps.resizeHeight)),
33
34
  overscan(nitro::ReactProp<std::optional<double>>::fromRawValue("OneKeyImage", "overscan", rawProps, sourceProps.overscan)),
34
35
  loadingStrategy(nitro::ReactProp<std::optional<OneKeyImageLoadingStrategy>>::fromRawValue("OneKeyImage", "loadingStrategy", rawProps, sourceProps.loadingStrategy)),
35
36
  placeholderColor(nitro::ReactProp<std::optional<std::string>>::fromRawValue("OneKeyImage", "placeholderColor", rawProps, sourceProps.placeholderColor)),
@@ -52,6 +53,7 @@ namespace margelo::nitro::onekeyimage::views {
52
53
  case hashString("optimizeTos"): return true;
53
54
  case hashString("round"): return true;
54
55
  case hashString("resizeWidth"): return true;
56
+ case hashString("resizeHeight"): return true;
55
57
  case hashString("overscan"): return true;
56
58
  case hashString("loadingStrategy"): return true;
57
59
  case hashString("placeholderColor"): return true;
@@ -58,6 +58,7 @@ namespace margelo::nitro::onekeyimage::views {
58
58
  nitro::ReactProp<std::optional<bool>> optimizeTos;
59
59
  nitro::ReactProp<std::optional<bool>> round;
60
60
  nitro::ReactProp<std::optional<double>> resizeWidth;
61
+ nitro::ReactProp<std::optional<double>> resizeHeight;
61
62
  nitro::ReactProp<std::optional<double>> overscan;
62
63
  nitro::ReactProp<std::optional<OneKeyImageLoadingStrategy>> loadingStrategy;
63
64
  nitro::ReactProp<std::optional<std::string>> placeholderColor;
@@ -80,6 +81,7 @@ namespace margelo::nitro::onekeyimage::views {
80
81
  optimizeTos.hasSameValue(other.optimizeTos) &&
81
82
  round.hasSameValue(other.round) &&
82
83
  resizeWidth.hasSameValue(other.resizeWidth) &&
84
+ resizeHeight.hasSameValue(other.resizeHeight) &&
83
85
  overscan.hasSameValue(other.overscan) &&
84
86
  loadingStrategy.hasSameValue(other.loadingStrategy) &&
85
87
  placeholderColor.hasSameValue(other.placeholderColor) &&
@@ -103,6 +105,7 @@ namespace margelo::nitro::onekeyimage::views {
103
105
  optimizeTos.isProvided() ||
104
106
  round.isProvided() ||
105
107
  resizeWidth.isProvided() ||
108
+ resizeHeight.isProvided() ||
106
109
  overscan.isProvided() ||
107
110
  loadingStrategy.isProvided() ||
108
111
  placeholderColor.isProvided() ||
@@ -14,6 +14,7 @@
14
14
  "optimizeTos": true,
15
15
  "round": true,
16
16
  "resizeWidth": true,
17
+ "resizeHeight": true,
17
18
  "overscan": true,
18
19
  "loadingStrategy": true,
19
20
  "placeholderColor": true,
@@ -36,6 +36,12 @@ export interface OneKeyImageNativeProps extends HybridViewProps {
36
36
  round?: boolean;
37
37
  /** Display width hint in layout units. Native applies the screen density. */
38
38
  resizeWidth?: number;
39
+ /**
40
+ * Display height hint in layout units. With `resizeWidth` it lets the
41
+ * pre-layout memory-cache probe derive the same decode thumbnail a preload
42
+ * with the same hints stored; omitted, the hint is a square of `resizeWidth`.
43
+ */
44
+ resizeHeight?: number;
39
45
  overscan?: number;
40
46
  loadingStrategy?: OneKeyImageLoadingStrategy;
41
47
  /** Theme-aware color used by static loading, error, and fallback states. */
@@ -45,7 +45,7 @@ export interface OneKeyImageProps extends Omit<OneKeyImageNativeProps, 'sourceUr
45
45
  onError?: MaybeWrappedCallback<(event: OneKeyImageErrorEvent) => void>;
46
46
  onLoadEnd?: MaybeWrappedCallback<() => void>;
47
47
  }
48
- export declare function OneKeyImage({ source, placeholder, fallback, variant, contentFit, cachePolicy, autoplay, recyclingKey, optimizeTos, round, resizeWidth, overscan, loadingStrategy, placeholderColor, hybridRef, onLoadStart, onLoad, onDisplay, onError, onLoadEnd, style, ...viewProps }: OneKeyImageProps): import("react/jsx-runtime").JSX.Element;
48
+ export declare function OneKeyImage({ source, placeholder, fallback, variant, contentFit, cachePolicy, autoplay, recyclingKey, optimizeTos, round, resizeWidth, resizeHeight, overscan, loadingStrategy, placeholderColor, hybridRef, onLoadStart, onLoad, onDisplay, onError, onLoadEnd, style, ...viewProps }: OneKeyImageProps): import("react/jsx-runtime").JSX.Element;
49
49
  export declare const OneKeyImageCache: {
50
50
  preload(sources: OneKeyImagePreloadInput[]): Promise<boolean>;
51
51
  clearMemory: () => Promise<void>;
@@ -156,6 +156,15 @@ namespace margelo::nitro::onekeyimage {
156
156
  static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* resizeWidth */)>("setResizeWidth");
157
157
  method(_javaPart, resizeWidth.has_value() ? jni::JDouble::valueOf(resizeWidth.value()) : nullptr);
158
158
  }
159
+ std::optional<double> JHybridOneKeyImageSpec::getResizeHeight() {
160
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getResizeHeight");
161
+ auto __result = method(_javaPart);
162
+ return __result != nullptr ? std::make_optional(__result->value()) : std::nullopt;
163
+ }
164
+ void JHybridOneKeyImageSpec::setResizeHeight(std::optional<double> resizeHeight) {
165
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* resizeHeight */)>("setResizeHeight");
166
+ method(_javaPart, resizeHeight.has_value() ? jni::JDouble::valueOf(resizeHeight.value()) : nullptr);
167
+ }
159
168
  std::optional<double> JHybridOneKeyImageSpec::getOverscan() {
160
169
  static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getOverscan");
161
170
  auto __result = method(_javaPart);
@@ -70,6 +70,8 @@ namespace margelo::nitro::onekeyimage {
70
70
  void setRound(std::optional<bool> round) override;
71
71
  std::optional<double> getResizeWidth() override;
72
72
  void setResizeWidth(std::optional<double> resizeWidth) override;
73
+ std::optional<double> getResizeHeight() override;
74
+ void setResizeHeight(std::optional<double> resizeHeight) override;
73
75
  std::optional<double> getOverscan() override;
74
76
  void setOverscan(std::optional<double> overscan) override;
75
77
  std::optional<OneKeyImageLoadingStrategy> getLoadingStrategy() override;
@@ -103,6 +103,11 @@ void JHybridOneKeyImageStateUpdater::updateViewProps(jni::alias_ref<jni::JClass>
103
103
  : !newProps->resizeWidth.hasSameValue(oldProps->resizeWidth)) {
104
104
  hybridView->setResizeWidth(newProps->resizeWidth.get());
105
105
  }
106
+ if (oldProps == nullptr
107
+ ? newProps->resizeHeight.isProvided()
108
+ : !newProps->resizeHeight.hasSameValue(oldProps->resizeHeight)) {
109
+ hybridView->setResizeHeight(newProps->resizeHeight.get());
110
+ }
106
111
  if (oldProps == nullptr
107
112
  ? newProps->overscan.isProvided()
108
113
  : !newProps->overscan.hasSameValue(oldProps->overscan)) {
@@ -87,6 +87,12 @@ abstract class HybridOneKeyImageSpec: HybridView() {
87
87
  @set:Keep
88
88
  abstract var resizeWidth: Double?
89
89
 
90
+ @get:DoNotStrip
91
+ @get:Keep
92
+ @set:DoNotStrip
93
+ @set:Keep
94
+ abstract var resizeHeight: Double?
95
+
90
96
  @get:DoNotStrip
91
97
  @get:Keep
92
98
  @set:DoNotStrip
@@ -148,6 +148,13 @@ namespace margelo::nitro::onekeyimage {
148
148
  inline void setResizeWidth(std::optional<double> resizeWidth) noexcept override {
149
149
  _swiftPart.setResizeWidth(resizeWidth);
150
150
  }
151
+ inline std::optional<double> getResizeHeight() noexcept override {
152
+ auto __result = _swiftPart.getResizeHeight();
153
+ return __result;
154
+ }
155
+ inline void setResizeHeight(std::optional<double> resizeHeight) noexcept override {
156
+ _swiftPart.setResizeHeight(resizeHeight);
157
+ }
151
158
  inline std::optional<double> getOverscan() noexcept override {
152
159
  auto __result = _swiftPart.getOverscan();
153
160
  return __result;
@@ -158,6 +158,12 @@ using namespace margelo::nitro::onekeyimage::views;
158
158
  : !newViewProps.resizeWidth.hasSameValue(oldViewProps->resizeWidth)) {
159
159
  swiftPart.setResizeWidth(newViewProps.resizeWidth.get());
160
160
  }
161
+ // resizeHeight: optional
162
+ if (oldViewProps == nullptr
163
+ ? newViewProps.resizeHeight.isProvided()
164
+ : !newViewProps.resizeHeight.hasSameValue(oldViewProps->resizeHeight)) {
165
+ swiftPart.setResizeHeight(newViewProps.resizeHeight.get());
166
+ }
161
167
  // overscan: optional
162
168
  if (oldViewProps == nullptr
163
169
  ? newViewProps.overscan.isProvided()
@@ -20,6 +20,7 @@ public protocol HybridOneKeyImageSpec_protocol: HybridObject, HybridView {
20
20
  var optimizeTos: Bool? { get set }
21
21
  var round: Bool? { get set }
22
22
  var resizeWidth: Double? { get set }
23
+ var resizeHeight: Double? { get set }
23
24
  var overscan: Double? { get set }
24
25
  var loadingStrategy: OneKeyImageLoadingStrategy? { get set }
25
26
  var placeholderColor: String? { get set }
@@ -340,6 +340,30 @@ open class HybridOneKeyImageSpec_cxx {
340
340
  }
341
341
  }
342
342
 
343
+ public final var resizeHeight: bridge.std__optional_double_ {
344
+ @inline(__always)
345
+ get {
346
+ return { () -> bridge.std__optional_double_ in
347
+ if let __unwrappedValue = self.__implementation.resizeHeight {
348
+ return bridge.create_std__optional_double_(__unwrappedValue)
349
+ } else {
350
+ return .init()
351
+ }
352
+ }()
353
+ }
354
+ @inline(__always)
355
+ set {
356
+ self.__implementation.resizeHeight = { () -> Double? in
357
+ if bridge.has_value_std__optional_double_(newValue) {
358
+ let __unwrapped = bridge.get_std__optional_double_(newValue)
359
+ return __unwrapped
360
+ } else {
361
+ return nil
362
+ }
363
+ }()
364
+ }
365
+ }
366
+
343
367
  public final var overscan: bridge.std__optional_double_ {
344
368
  @inline(__always)
345
369
  get {
@@ -34,6 +34,8 @@ namespace margelo::nitro::onekeyimage {
34
34
  prototype.registerHybridSetter("round", &HybridOneKeyImageSpec::setRound);
35
35
  prototype.registerHybridGetter("resizeWidth", &HybridOneKeyImageSpec::getResizeWidth);
36
36
  prototype.registerHybridSetter("resizeWidth", &HybridOneKeyImageSpec::setResizeWidth);
37
+ prototype.registerHybridGetter("resizeHeight", &HybridOneKeyImageSpec::getResizeHeight);
38
+ prototype.registerHybridSetter("resizeHeight", &HybridOneKeyImageSpec::setResizeHeight);
37
39
  prototype.registerHybridGetter("overscan", &HybridOneKeyImageSpec::getOverscan);
38
40
  prototype.registerHybridSetter("overscan", &HybridOneKeyImageSpec::setOverscan);
39
41
  prototype.registerHybridGetter("loadingStrategy", &HybridOneKeyImageSpec::getLoadingStrategy);
@@ -80,6 +80,8 @@ namespace margelo::nitro::onekeyimage {
80
80
  virtual void setRound(std::optional<bool> round) = 0;
81
81
  virtual std::optional<double> getResizeWidth() = 0;
82
82
  virtual void setResizeWidth(std::optional<double> resizeWidth) = 0;
83
+ virtual std::optional<double> getResizeHeight() = 0;
84
+ virtual void setResizeHeight(std::optional<double> resizeHeight) = 0;
83
85
  virtual std::optional<double> getOverscan() = 0;
84
86
  virtual void setOverscan(std::optional<double> overscan) = 0;
85
87
  virtual std::optional<OneKeyImageLoadingStrategy> getLoadingStrategy() = 0;
@@ -30,6 +30,7 @@ namespace margelo::nitro::onekeyimage::views {
30
30
  optimizeTos(nitro::ReactProp<std::optional<bool>>::fromRawValue("OneKeyImage", "optimizeTos", rawProps, sourceProps.optimizeTos)),
31
31
  round(nitro::ReactProp<std::optional<bool>>::fromRawValue("OneKeyImage", "round", rawProps, sourceProps.round)),
32
32
  resizeWidth(nitro::ReactProp<std::optional<double>>::fromRawValue("OneKeyImage", "resizeWidth", rawProps, sourceProps.resizeWidth)),
33
+ resizeHeight(nitro::ReactProp<std::optional<double>>::fromRawValue("OneKeyImage", "resizeHeight", rawProps, sourceProps.resizeHeight)),
33
34
  overscan(nitro::ReactProp<std::optional<double>>::fromRawValue("OneKeyImage", "overscan", rawProps, sourceProps.overscan)),
34
35
  loadingStrategy(nitro::ReactProp<std::optional<OneKeyImageLoadingStrategy>>::fromRawValue("OneKeyImage", "loadingStrategy", rawProps, sourceProps.loadingStrategy)),
35
36
  placeholderColor(nitro::ReactProp<std::optional<std::string>>::fromRawValue("OneKeyImage", "placeholderColor", rawProps, sourceProps.placeholderColor)),
@@ -52,6 +53,7 @@ namespace margelo::nitro::onekeyimage::views {
52
53
  case hashString("optimizeTos"): return true;
53
54
  case hashString("round"): return true;
54
55
  case hashString("resizeWidth"): return true;
56
+ case hashString("resizeHeight"): return true;
55
57
  case hashString("overscan"): return true;
56
58
  case hashString("loadingStrategy"): return true;
57
59
  case hashString("placeholderColor"): return true;
@@ -58,6 +58,7 @@ namespace margelo::nitro::onekeyimage::views {
58
58
  nitro::ReactProp<std::optional<bool>> optimizeTos;
59
59
  nitro::ReactProp<std::optional<bool>> round;
60
60
  nitro::ReactProp<std::optional<double>> resizeWidth;
61
+ nitro::ReactProp<std::optional<double>> resizeHeight;
61
62
  nitro::ReactProp<std::optional<double>> overscan;
62
63
  nitro::ReactProp<std::optional<OneKeyImageLoadingStrategy>> loadingStrategy;
63
64
  nitro::ReactProp<std::optional<std::string>> placeholderColor;
@@ -80,6 +81,7 @@ namespace margelo::nitro::onekeyimage::views {
80
81
  optimizeTos.hasSameValue(other.optimizeTos) &&
81
82
  round.hasSameValue(other.round) &&
82
83
  resizeWidth.hasSameValue(other.resizeWidth) &&
84
+ resizeHeight.hasSameValue(other.resizeHeight) &&
83
85
  overscan.hasSameValue(other.overscan) &&
84
86
  loadingStrategy.hasSameValue(other.loadingStrategy) &&
85
87
  placeholderColor.hasSameValue(other.placeholderColor) &&
@@ -103,6 +105,7 @@ namespace margelo::nitro::onekeyimage::views {
103
105
  optimizeTos.isProvided() ||
104
106
  round.isProvided() ||
105
107
  resizeWidth.isProvided() ||
108
+ resizeHeight.isProvided() ||
106
109
  overscan.isProvided() ||
107
110
  loadingStrategy.isProvided() ||
108
111
  placeholderColor.isProvided() ||
@@ -14,6 +14,7 @@
14
14
  "optimizeTos": true,
15
15
  "round": true,
16
16
  "resizeWidth": true,
17
+ "resizeHeight": true,
17
18
  "overscan": true,
18
19
  "loadingStrategy": true,
19
20
  "placeholderColor": true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-image",
3
- "version": "3.0.156",
3
+ "version": "3.0.157",
4
4
  "description": "High-performance native image view for OneKey",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -81,7 +81,7 @@
81
81
  "typescript": "^5.9.2"
82
82
  },
83
83
  "peerDependencies": {
84
- "@onekeyfe/react-native-skeleton": "3.0.156",
84
+ "@onekeyfe/react-native-skeleton": "3.0.157",
85
85
  "react": "*",
86
86
  "react-native": "*",
87
87
  "react-native-nitro-modules": "0.37.0"
@@ -47,6 +47,12 @@ export interface OneKeyImageNativeProps extends HybridViewProps {
47
47
  round?: boolean;
48
48
  /** Display width hint in layout units. Native applies the screen density. */
49
49
  resizeWidth?: number;
50
+ /**
51
+ * Display height hint in layout units. With `resizeWidth` it lets the
52
+ * pre-layout memory-cache probe derive the same decode thumbnail a preload
53
+ * with the same hints stored; omitted, the hint is a square of `resizeWidth`.
54
+ */
55
+ resizeHeight?: number;
50
56
  overscan?: number;
51
57
  loadingStrategy?: OneKeyImageLoadingStrategy;
52
58
  /** Theme-aware color used by static loading, error, and fallback states. */
package/src/index.tsx CHANGED
@@ -155,6 +155,7 @@ export function OneKeyImage({
155
155
  optimizeTos = true,
156
156
  round = false,
157
157
  resizeWidth,
158
+ resizeHeight,
158
159
  overscan = 1.1,
159
160
  loadingStrategy = OneKeyImageLoadingStrategy.STATIC,
160
161
  placeholderColor,
@@ -176,7 +177,7 @@ export function OneKeyImage({
176
177
  normalized?.headers ?? {}
177
178
  )}|${resolvedCachePolicy}|${recyclingKey ?? ''}|${contentFit}|${
178
179
  optimizeTos ? '1' : '0'
179
- }|${resizeWidth ?? ''}|${overscan}`;
180
+ }|${resizeWidth ?? ''}|${resizeHeight ?? ''}|${overscan}`;
180
181
  const hasSource = normalized != null;
181
182
  const hasOverlay = placeholder != null || fallback != null;
182
183
  type LoadState = {
@@ -373,6 +374,7 @@ export function OneKeyImage({
373
374
  optimizeTos,
374
375
  round,
375
376
  resizeWidth,
377
+ resizeHeight,
376
378
  overscan,
377
379
  loadingStrategy:
378
380
  placeholder == null ? loadingStrategy : OneKeyImageLoadingStrategy.NONE,