@sbaiahmed1/react-native-blur 4.5.5-beta.1 → 4.5.5-beta.3

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
 
@@ -35,6 +38,8 @@ class ReactNativeProgressiveBlurView : FrameLayout {
35
38
  private var currentStartOffset = 0.0f
36
39
  private var hasExplicitBackground: Boolean = false
37
40
  private var isBlurInitialized: Boolean = false
41
+ private var initRunnable: Runnable? = null
42
+ private var swapRootRunnable: Runnable? = null
38
43
 
39
44
  companion object {
40
45
  private const val TAG = "ReactNativeProgressiveBlur"
@@ -102,9 +107,12 @@ class ReactNativeProgressiveBlurView : FrameLayout {
102
107
  super.onAttachedToWindow()
103
108
 
104
109
  if (!isBlurInitialized) {
105
- post {
110
+ val runnable = Runnable {
111
+ initRunnable = null
106
112
  initializeBlurChild()
107
113
  }
114
+ initRunnable = runnable
115
+ post(runnable)
108
116
  }
109
117
  }
110
118
 
@@ -132,9 +140,12 @@ class ReactNativeProgressiveBlurView : FrameLayout {
132
140
  }
133
141
 
134
142
  // Swap blur root after BlurView is attached (deferred to let it attach first)
135
- blurView?.post {
143
+ val swapRunnable = Runnable {
144
+ swapRootRunnable = null
136
145
  swapBlurRootToScreenAncestor()
137
146
  }
147
+ swapRootRunnable = swapRunnable
148
+ blurView?.post(swapRunnable)
138
149
 
139
150
  isBlurInitialized = true
140
151
  logDebug("Initialized progressive blur with blur + gradient approach")
@@ -207,10 +218,11 @@ class ReactNativeProgressiveBlurView : FrameLayout {
207
218
 
208
219
  /**
209
220
  * Falls back to android.R.id.content or the activity root view.
221
+ * Tries ReactContext.currentActivity first, then unwraps ContextWrapper chain.
210
222
  */
211
223
  private fun getContentViewFallback(): ViewGroup? {
212
224
  try {
213
- val activity = context as? android.app.Activity
225
+ val activity = getActivityFromContext()
214
226
  activity?.findViewById<ViewGroup>(android.R.id.content)?.let { return it }
215
227
  } catch (e: Exception) {
216
228
  logDebug("Could not access activity content view: ${e.message}")
@@ -218,6 +230,23 @@ class ReactNativeProgressiveBlurView : FrameLayout {
218
230
  return this.parent as? ViewGroup
219
231
  }
220
232
 
233
+ /**
234
+ * Resolves an Activity from the view's context.
235
+ * Priority: ReactContext.currentActivity > ContextWrapper unwrap chain.
236
+ */
237
+ private fun getActivityFromContext(): Activity? {
238
+ // Try ReactContext first (most common in React Native)
239
+ (context as? ReactContext)?.currentActivity?.let { return it }
240
+
241
+ // Unwrap ContextWrapper chain to find an Activity
242
+ var ctx: Context? = context
243
+ while (ctx != null) {
244
+ if (ctx is Activity) return ctx
245
+ ctx = (ctx as? ContextWrapper)?.baseContext
246
+ }
247
+ return null
248
+ }
249
+
221
250
  override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
222
251
  val width = MeasureSpec.getSize(widthMeasureSpec)
223
252
  val height = MeasureSpec.getSize(heightMeasureSpec)
@@ -365,7 +394,29 @@ class ReactNativeProgressiveBlurView : FrameLayout {
365
394
  fun cleanup() {
366
395
  hasExplicitBackground = false
367
396
  isBlurInitialized = false
368
- removeCallbacks(null)
397
+ initRunnable?.let { removeCallbacks(it) }
398
+ initRunnable = null
399
+ swapRootRunnable?.let { runnable ->
400
+ blurView?.removeCallbacks(runnable)
401
+ }
402
+ swapRootRunnable = null
403
+
404
+ // Unregister the OnPreDrawListener from whatever root it was moved to,
405
+ // preventing callbacks into a detached BlurView and avoiding leaks.
406
+ blurView?.let { bv ->
407
+ val listener = bv.preDrawListener
408
+ val decor = bv.mDecorView
409
+ if (listener != null && decor != null) {
410
+ try {
411
+ decor.viewTreeObserver.removeOnPreDrawListener(listener)
412
+ } catch (e: Exception) {
413
+ logDebug("Could not remove pre-draw listener during cleanup: ${e.message}")
414
+ }
415
+ }
416
+ bv.mDecorView = null
417
+ bv.mDifferentRoot = false
418
+ }
419
+
369
420
  logDebug("View cleaned up")
370
421
  }
371
422
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sbaiahmed1/react-native-blur",
3
- "version": "4.5.5-beta.1",
3
+ "version": "4.5.5-beta.3",
4
4
  "description": "React native modern blur view",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",