@sbaiahmed1/react-native-blur 4.5.5-beta.2 → 4.5.5-beta.4

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.
@@ -1,6 +1,8 @@
1
1
  package com.sbaiahmed1.reactnativeblur
2
2
 
3
+ import android.app.Activity
3
4
  import android.content.Context
5
+ import android.content.ContextWrapper
4
6
  import android.graphics.Canvas
5
7
  import android.graphics.Color
6
8
  import android.graphics.LinearGradient
@@ -14,6 +16,7 @@ import android.view.View
14
16
  import android.view.ViewGroup
15
17
  import android.widget.FrameLayout
16
18
  import android.view.View.MeasureSpec
19
+ import com.facebook.react.bridge.ReactContext
17
20
  import com.qmdeve.blurview.widget.BlurView
18
21
  import kotlin.math.max
19
22
 
@@ -157,7 +160,9 @@ class ReactNativeProgressiveBlurView : FrameLayout {
157
160
  * Redirects the internal BlurView's blur capture root from the activity decor view
158
161
  * to the nearest react-native-screens Screen ancestor.
159
162
  *
160
- * BaseBlurView has public mDecorView and preDrawListener fields, so no reflection needed.
163
+ * BaseBlurView (QmBlurView 1.1.4) field visibility:
164
+ * public — mDecorView, mDifferentRoot, preDrawListener (direct access)
165
+ * private — mForceRedraw (requires reflection)
161
166
  */
162
167
  private fun swapBlurRootToScreenAncestor() {
163
168
  val bv = blurView ?: return
@@ -175,15 +180,24 @@ class ReactNativeProgressiveBlurView : FrameLayout {
175
180
  logDebug("Could not remove old pre-draw listener: ${e.message}")
176
181
  }
177
182
 
178
- // Set new root
183
+ // Set new root (public field)
179
184
  bv.mDecorView = newRoot
180
185
 
181
186
  // Add listener to new root
182
187
  newRoot.viewTreeObserver.addOnPreDrawListener(listener)
183
188
 
184
- // Update mDifferentRoot flag
189
+ // Update mDifferentRoot flag (public field)
185
190
  bv.mDifferentRoot = newRoot.rootView != bv.rootView
186
191
 
192
+ // Force a redraw (private field — requires reflection)
193
+ try {
194
+ val forceRedrawField = bv.javaClass.superclass.getDeclaredField("mForceRedraw")
195
+ forceRedrawField.isAccessible = true
196
+ forceRedrawField.setBoolean(bv, true)
197
+ } catch (e: NoSuchFieldException) {
198
+ logWarning("Could not set mForceRedraw via reflection: ${e.message}")
199
+ }
200
+
187
201
  logDebug("Progressive blur: swapped root to ${newRoot.javaClass.simpleName}")
188
202
  }
189
203
  } catch (e: Exception) {
@@ -215,10 +229,11 @@ class ReactNativeProgressiveBlurView : FrameLayout {
215
229
 
216
230
  /**
217
231
  * Falls back to android.R.id.content or the activity root view.
232
+ * Tries ReactContext.currentActivity first, then unwraps ContextWrapper chain.
218
233
  */
219
234
  private fun getContentViewFallback(): ViewGroup? {
220
235
  try {
221
- val activity = context as? android.app.Activity
236
+ val activity = getActivityFromContext()
222
237
  activity?.findViewById<ViewGroup>(android.R.id.content)?.let { return it }
223
238
  } catch (e: Exception) {
224
239
  logDebug("Could not access activity content view: ${e.message}")
@@ -226,6 +241,23 @@ class ReactNativeProgressiveBlurView : FrameLayout {
226
241
  return this.parent as? ViewGroup
227
242
  }
228
243
 
244
+ /**
245
+ * Resolves an Activity from the view's context.
246
+ * Priority: ReactContext.currentActivity > ContextWrapper unwrap chain.
247
+ */
248
+ private fun getActivityFromContext(): Activity? {
249
+ // Try ReactContext first (most common in React Native)
250
+ (context as? ReactContext)?.currentActivity?.let { return it }
251
+
252
+ // Unwrap ContextWrapper chain to find an Activity
253
+ var ctx: Context? = context
254
+ while (ctx != null) {
255
+ if (ctx is Activity) return ctx
256
+ ctx = (ctx as? ContextWrapper)?.baseContext
257
+ }
258
+ return null
259
+ }
260
+
229
261
  override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
230
262
  val width = MeasureSpec.getSize(widthMeasureSpec)
231
263
  val height = MeasureSpec.getSize(heightMeasureSpec)
@@ -379,6 +411,23 @@ class ReactNativeProgressiveBlurView : FrameLayout {
379
411
  blurView?.removeCallbacks(runnable)
380
412
  }
381
413
  swapRootRunnable = null
414
+
415
+ // Unregister the OnPreDrawListener from whatever root it was moved to,
416
+ // preventing callbacks into a detached BlurView and avoiding leaks.
417
+ blurView?.let { bv ->
418
+ val listener = bv.preDrawListener
419
+ val decor = bv.mDecorView
420
+ if (listener != null && decor != null) {
421
+ try {
422
+ decor.viewTreeObserver.removeOnPreDrawListener(listener)
423
+ } catch (e: Exception) {
424
+ logDebug("Could not remove pre-draw listener during cleanup: ${e.message}")
425
+ }
426
+ }
427
+ bv.mDecorView = null
428
+ bv.mDifferentRoot = false
429
+ }
430
+
382
431
  logDebug("View cleaned up")
383
432
  }
384
433
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sbaiahmed1/react-native-blur",
3
- "version": "4.5.5-beta.2",
3
+ "version": "4.5.5-beta.4",
4
4
  "description": "React native modern blur view",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",