bump version and get rid of the expo-scroll-edge-effect patch
This commit is contained in:
+1
-1
@@ -105,7 +105,7 @@
|
|||||||
"@bsky.app/expo-dynamic-app-icon": "^1.8.5",
|
"@bsky.app/expo-dynamic-app-icon": "^1.8.5",
|
||||||
"@bsky.app/expo-guess-language": "^0.2.8",
|
"@bsky.app/expo-guess-language": "^0.2.8",
|
||||||
"@bsky.app/expo-image-crop-tool": "^0.5.1",
|
"@bsky.app/expo-image-crop-tool": "^0.5.1",
|
||||||
"@bsky.app/expo-scroll-edge-effect": "^0.1.4",
|
"@bsky.app/expo-scroll-edge-effect": "^0.1.9",
|
||||||
"@bsky.app/expo-translate-text": "^0.2.9",
|
"@bsky.app/expo-translate-text": "^0.2.9",
|
||||||
"@bsky.app/peek-menu": "^0.3.1",
|
"@bsky.app/peek-menu": "^0.3.1",
|
||||||
"@bsky.app/sift": "^0.3.9",
|
"@bsky.app/sift": "^0.3.9",
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
diff --git a/ios/ExpoScrollEdgeEffectView.swift b/ios/ExpoScrollEdgeEffectView.swift
|
|
||||||
index 44b03cc7c33e770585e232635b7db2dfd21aee8b..6b24e55cf97c96142e53172dc9097c4e054d4d53 100644
|
|
||||||
--- a/ios/ExpoScrollEdgeEffectView.swift
|
|
||||||
+++ b/ios/ExpoScrollEdgeEffectView.swift
|
|
||||||
@@ -4,10 +4,14 @@ import UIKit
|
|
||||||
class ExpoScrollEdgeEffectView: ExpoView {
|
|
||||||
private var currentInteraction: NSObject?
|
|
||||||
|
|
||||||
+ private var isAttached = false
|
|
||||||
+ private var resolveAttempts = 0
|
|
||||||
+ private let maxResolveAttempts = 30
|
|
||||||
+
|
|
||||||
var scrollViewTag: Int? {
|
|
||||||
didSet {
|
|
||||||
if scrollViewTag != oldValue {
|
|
||||||
- updateInteraction()
|
|
||||||
+ scheduleResolve()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,7 +19,7 @@ class ExpoScrollEdgeEffectView: ExpoView {
|
|
||||||
var edge: String = "top" {
|
|
||||||
didSet {
|
|
||||||
if edge != oldValue {
|
|
||||||
- updateInteraction()
|
|
||||||
+ scheduleResolve()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,7 +27,7 @@ class ExpoScrollEdgeEffectView: ExpoView {
|
|
||||||
var effect: String = "automatic" {
|
|
||||||
didSet {
|
|
||||||
if effect != oldValue {
|
|
||||||
- updateInteraction()
|
|
||||||
+ scheduleResolve()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -42,17 +46,39 @@ class ExpoScrollEdgeEffectView: ExpoView {
|
|
||||||
override func didMoveToWindow() {
|
|
||||||
super.didMoveToWindow()
|
|
||||||
if window != nil {
|
|
||||||
+ scheduleResolve()
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ override func layoutSubviews() {
|
|
||||||
+ super.layoutSubviews()
|
|
||||||
+
|
|
||||||
+ if !isAttached, window != nil, scrollViewTag != nil, resolveAttempts < maxResolveAttempts {
|
|
||||||
updateInteraction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ private func scheduleResolve() {
|
|
||||||
+ resolveAttempts = 0
|
|
||||||
+ updateInteraction()
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
private func updateInteraction() {
|
|
||||||
removeInteraction()
|
|
||||||
|
|
||||||
guard window != nil else { return }
|
|
||||||
guard let tag = scrollViewTag else { return }
|
|
||||||
guard #available(iOS 26, *) else { return }
|
|
||||||
- guard let scrollView = resolveScrollView(tag: tag) else { return }
|
|
||||||
+ guard let scrollView = resolveScrollView(tag: tag) else {
|
|
||||||
+ if resolveAttempts < maxResolveAttempts {
|
|
||||||
+ resolveAttempts += 1
|
|
||||||
+ setNeedsLayout()
|
|
||||||
+ }
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ resolveAttempts = 0
|
|
||||||
+ isAttached = true
|
|
||||||
|
|
||||||
let resolvedEdge = self.resolveEdge(edge)
|
|
||||||
let resolvedStyle = self.resolveEffectStyle(effect)
|
|
||||||
@@ -79,6 +105,8 @@ class ExpoScrollEdgeEffectView: ExpoView {
|
|
||||||
}
|
|
||||||
|
|
||||||
private func removeInteraction() {
|
|
||||||
+ isAttached = false
|
|
||||||
+
|
|
||||||
guard #available(iOS 26, *) else { return }
|
|
||||||
|
|
||||||
if let interaction = currentInteraction as? UIScrollEdgeElementContainerInteraction {
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
# @bsky.app\_\_expo-scroll-edge-effect.patch
|
|
||||||
|
|
||||||
Fixes the iOS 26 scroll edge effect (the blur under the status bar) failing to
|
|
||||||
attach on the New Architecture (Fabric).
|
|
||||||
|
|
||||||
## Why
|
|
||||||
|
|
||||||
The native view resolves the target scroll view by React tag:
|
|
||||||
`scrollViewTag` (published from JS when the scroll view mounts) ->
|
|
||||||
`appContext.findView(withTag:)` -> attach a `UIScrollEdgeElementContainerInteraction`.
|
|
||||||
|
|
||||||
On Paper this resolved on the first try, because view-by-tag registration was
|
|
||||||
serialized through the single UIManager batch pipeline - by the time the tag
|
|
||||||
prop reached native, the scroll view was already in the registry.
|
|
||||||
|
|
||||||
On Fabric there is no synchronous tag->view registry. The scroll view's
|
|
||||||
`ComponentView` is registered when its mount transaction is applied, which is
|
|
||||||
deferred relative to the JS commit that set the tag. So the one-shot
|
|
||||||
`resolveScrollView` runs before the view is mounted and returns nil, the
|
|
||||||
interaction never attaches, and the blur is lost. (The un-gated case happened to
|
|
||||||
work only because the header's `didMoveToWindow` provided a late second attempt;
|
|
||||||
a list mounted later - e.g. behind an `isActive` gate - had no such retry.)
|
|
||||||
|
|
||||||
## What it does
|
|
||||||
|
|
||||||
Makes resolution event-driven and self-healing instead of one-shot:
|
|
||||||
|
|
||||||
- When `resolveScrollView` returns nil, it bumps a bounded counter and calls
|
|
||||||
`setNeedsLayout()`; `layoutSubviews()` re-attempts as sibling views mount, so
|
|
||||||
it retries exactly when the scroll view actually appears - no fixed timer.
|
|
||||||
- `isAttached` stops re-running once resolved (no teardown/re-attach churn).
|
|
||||||
- `resolveAttempts` / `maxResolveAttempts` bound the retries so a
|
|
||||||
permanently-absent scroll view (list not rendered) cannot spin layout forever.
|
|
||||||
- The budget is reset on every "fresh" trigger (prop change, entering the
|
|
||||||
window) via `scheduleResolve()`, so each new tag gets a full retry budget.
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- iOS only; gated behind `#available(iOS 26, *)`.
|
|
||||||
- This mirrors how `react-native-screens` handles the same effect on Fabric
|
|
||||||
(resolve from the live view hierarchy and re-apply on mount/layout lifecycle
|
|
||||||
rather than a single tag lookup). A cleaner long-term fix would move
|
|
||||||
resolution to the scroll-view side, but this is the minimal change to the
|
|
||||||
existing tag-based design.
|
|
||||||
@@ -20,7 +20,6 @@ allowBuilds:
|
|||||||
'esbuild': true
|
'esbuild': true
|
||||||
'unrs-resolver': true
|
'unrs-resolver': true
|
||||||
patchedDependencies:
|
patchedDependencies:
|
||||||
'@bsky.app/expo-scroll-edge-effect': patches/@bsky.app__expo-scroll-edge-effect.patch
|
|
||||||
'@sentry/expo-upload-sourcemaps@8.18.0': patches/@sentry__expo-upload-sourcemaps@8.18.0.patch
|
'@sentry/expo-upload-sourcemaps@8.18.0': patches/@sentry__expo-upload-sourcemaps@8.18.0.patch
|
||||||
expo-age-range@0.2.18: patches/expo-age-range@0.2.18.patch
|
expo-age-range@0.2.18: patches/expo-age-range@0.2.18.patch
|
||||||
'expo-haptics@15.0.8': patches/expo-haptics@15.0.8.patch
|
'expo-haptics@15.0.8': patches/expo-haptics@15.0.8.patch
|
||||||
|
|||||||
Reference in New Issue
Block a user