@onekeyfe/react-native-pager-view 3.0.162 → 3.0.163

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.
@@ -364,13 +364,14 @@ class CollapsiblePagerHost(context: Context) : NestedScrollableHost(context), Ne
364
364
  fun removeAllReactChildren() {
365
365
  releaseRefreshForeground()
366
366
  detachPrimaryScrollObserver()
367
- for (recycler in originalRecyclerPadding.keys.toList()) {
367
+ // Weak keys may disappear after size is read; Collection.toArray tolerates this.
368
+ for (recycler in originalRecyclerPadding.keys.toTypedArray()) {
368
369
  restoreRecyclerInsets(recycler)
369
370
  }
370
- for (scroller in originalScrollerPadding.keys.toList()) {
371
+ for (scroller in originalScrollerPadding.keys.toTypedArray()) {
371
372
  restoreNativeScrollerInsets(scroller)
372
373
  }
373
- for (scroller in ownedScrollerKeys.keys.toList()) restoreOwnedScrollerInsets(scroller)
374
+ for (scroller in ownedScrollerKeys.keys.toTypedArray()) restoreOwnedScrollerInsets(scroller)
374
375
  headerView?.let { view -> super.removeView(view) }
375
376
  stickyHeaderView?.let { view -> super.removeView(view) }
376
377
  headerView = null
@@ -1504,13 +1505,14 @@ class CollapsiblePagerHost(context: Context) : NestedScrollableHost(context), Ne
1504
1505
  nestedNativeGestureStarted = false
1505
1506
  viewTreeObserver.removeOnPreDrawListener(pageContentLayoutListener)
1506
1507
  detachPrimaryScrollObserver()
1507
- for (recycler in originalRecyclerPadding.keys.toList()) {
1508
+ // Snapshot live keys before restoration removes their padding records.
1509
+ for (recycler in originalRecyclerPadding.keys.toTypedArray()) {
1508
1510
  restoreRecyclerInsets(recycler)
1509
1511
  }
1510
- for (scroller in originalScrollerPadding.keys.toList()) {
1512
+ for (scroller in originalScrollerPadding.keys.toTypedArray()) {
1511
1513
  restoreNativeScrollerInsets(scroller)
1512
1514
  }
1513
- for (scroller in ownedScrollerKeys.keys.toList()) restoreOwnedScrollerInsets(scroller)
1515
+ for (scroller in ownedScrollerKeys.keys.toTypedArray()) restoreOwnedScrollerInsets(scroller)
1514
1516
  log(
1515
1517
  "host-detach generation=$attachmentGeneration inner=$selectedPage " +
1516
1518
  "outer=${outerPagerIndex()} nativePages=${adapter.itemCount}",
package/docs/SPEC.md CHANGED
@@ -453,3 +453,73 @@ The focused policy regression includes nonzero caller left/right/bottom padding,
453
453
  nonzero prior native insets, explicit caller padding changes/clear, and initial
454
454
  discovery before ownership. Current Home zero-padding behavior is unchanged by
455
455
  this ownership guard.
456
+
457
+ ## Weak padding-record cleanup
458
+
459
+ Status: Implemented. Android detach/reattach acceptance passed on the
460
+ pre-migration host described below. Remove-all and owned NativeScroller cleanup
461
+ have source and focused regression coverage; current-host device acceptance is
462
+ pending.
463
+
464
+ ### Scope and ownership
465
+
466
+ This specification covers restoring child scroll insets when a collapsible pager
467
+ detaches or removes all React children. Other pager behavior remains documented
468
+ in the package README. Navigation animations belong to the consuming app.
469
+
470
+ The native host owns its temporary inset changes and original-padding records.
471
+ Android lifecycle callbacks and restoration run on the UI thread. Garbage
472
+ collection can clear weak child references independently of that thread.
473
+
474
+ ### API, lifecycle, and identity
475
+
476
+ No public props, events, defaults, or serialization formats change. Detaching
477
+ and removing all children must restore the original insets of every still-live
478
+ tracked RecyclerView, native ScrollView, and owned NativeScroller viewport.
479
+ Restoration may remove entries from the tracking maps. Reattaching must remain supported.
480
+
481
+ Padding records are keyed by native child identity using weak references. The
482
+ host must not retain removed scroll children solely for later cleanup. A cleanup
483
+ snapshot temporarily holds surviving children strongly until restoration ends.
484
+
485
+ ### Platforms and failure handling
486
+
487
+ Android uses WeakHashMap padding records. Its snapshot must tolerate keys being
488
+ collected between reading the collection size and enumerating it, including
489
+ single-entry and multiple-entry maps. Collected children require no restoration;
490
+ they must not cause NoSuchElementException. Live children must not be skipped
491
+ because restoration changes the map.
492
+
493
+ iOS uses weak-key NSMapTable records and keyEnumerator.allObjects snapshots in
494
+ restoreDetachedScrollInsets. Its implementation is unchanged. Web has no Android
495
+ native-padding records and is unaffected.
496
+
497
+ ### Resource budget
498
+
499
+ Cleanup performs one snapshot and one restoration per surviving tracked child
500
+ on the UI thread. Temporary storage is proportional to the existing padding
501
+ records; no new persistent cache, retry, background task, or bridge traffic is
502
+ introduced. This change makes no frame-rate claim.
503
+
504
+ ### Conformance and acceptance
505
+
506
+ - Source: android/src/main/java/com/reactnativepagerview/CollapsiblePagerHost.kt,
507
+ removeAllReactChildren and onDetachedFromWindow.
508
+ - Focused JVM regression: tests/kotlin/WeakPaddingSnapshotTest.kt checks a
509
+ shrinking weak-key collection and restoration that removes snapshot entries.
510
+ - The same regression passed seven assertions on Android 36 ART using Kotlin
511
+ 2.1.20. Compile it without additional dependencies, then run its main function.
512
+ - Android acceptance: build the native host, repeatedly navigate from a populated
513
+ Market pager into stock/token details and back, and exercise modal dismissal.
514
+ Check native fatal logs and pager scroll/header state after returning.
515
+ - Runtime evidence on 2026-10-08 against the pre-migration host (1e1809509):
516
+ four NVDA detail visits and gesture returns,
517
+ BTC detail, quick settings Sheet and chart settings modal dismissal, Market
518
+ Perps tab entry/return, and header collapse/expand passed. The app retained its
519
+ PID and produced no app-native fatal crash during this run.
520
+ - Source and JVM checks do not establish native device acceptance or iOS visual
521
+ parity. Update runtime status only after the actual app has been exercised.
522
+
523
+ The newly merged NativeScroller viewport tracking uses the same weak-key
524
+ snapshot rule. Its cleanup has source and focused regression coverage; the
525
+ pre-migration runtime checks above do not establish its device acceptance.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-pager-view",
3
- "version": "3.0.162",
3
+ "version": "3.0.163",
4
4
  "description": "React Native wrapper for Android and iOS ViewPager",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/module/index.js",
@@ -51,11 +51,14 @@
51
51
  ],
52
52
  "repository": {
53
53
  "type": "git",
54
- "url": "git+https://github.com/nicholasxuu/app-modules.git",
54
+ "url": "git+https://github.com/OneKeyHQ/app-modules.git",
55
55
  "directory": "native-views/react-native-pager-view"
56
56
  },
57
57
  "author": "OneKey",
58
- "homepage": "https://github.com/nicholasxuu/app-modules#readme",
58
+ "bugs": {
59
+ "url": "https://github.com/OneKeyHQ/app-modules/issues"
60
+ },
61
+ "homepage": "https://github.com/OneKeyHQ/app-modules/tree/main/native-views/react-native-pager-view#readme",
59
62
  "license": "MIT",
60
63
  "publishConfig": {
61
64
  "registry": "https://registry.npmjs.org/",
@@ -69,7 +72,7 @@
69
72
  "typescript": "^5.9.2"
70
73
  },
71
74
  "peerDependencies": {
72
- "@onekeyfe/react-native-native-logger": "3.0.162",
75
+ "@onekeyfe/react-native-native-logger": "3.0.163",
73
76
  "react": "*",
74
77
  "react-native": "*"
75
78
  },