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

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.Color
5
7
  import android.graphics.Outline
6
8
  import android.util.AttributeSet
@@ -10,6 +12,7 @@ import android.view.View
10
12
  import android.view.ViewGroup
11
13
  import android.view.ViewOutlineProvider
12
14
  import android.view.ViewTreeObserver
15
+ import com.facebook.react.bridge.ReactContext
13
16
  import com.qmdeve.blurview.widget.BlurViewGroup
14
17
  import com.qmdeve.blurview.base.BaseBlurViewGroup
15
18
  import androidx.core.graphics.toColorInt
@@ -188,10 +191,13 @@ class ReactNativeBlurView : BlurViewGroup {
188
191
 
189
192
  /**
190
193
  * Finds the optimal view to use as blur capture root.
191
- * Priority: nearest react-native-screens Screen > android.R.id.content > parent
194
+ * Priority: nearest react-native-screens Screen > android.R.id.content in parent chain > activity content > parent
195
+ *
196
+ * This handles both regular screens and modals — modals have their own window/view tree,
197
+ * so we walk up the parent chain for android.R.id.content before falling back to the activity.
192
198
  */
193
199
  private fun findOptimalBlurRoot(): ViewGroup? {
194
- return findNearestScreenAncestor() ?: getContentViewFallback()
200
+ return findNearestScreenAncestor() ?: getAppRootFallback()
195
201
  }
196
202
 
197
203
  /**
@@ -210,18 +216,45 @@ class ReactNativeBlurView : BlurViewGroup {
210
216
  }
211
217
 
212
218
  /**
213
- * Falls back to android.R.id.content or the activity root view.
219
+ * Walks up the view parent chain looking for android.R.id.content (works in modals
220
+ * which have their own content root), then falls back to the activity's content view.
214
221
  */
215
- private fun getContentViewFallback(): ViewGroup? {
222
+ private fun getAppRootFallback(): ViewGroup? {
223
+ // Walk up the parent chain — catches modals which have their own android.R.id.content
224
+ var parent = this.parent
225
+ while (parent != null) {
226
+ if (parent is ViewGroup && parent.id == android.R.id.content) {
227
+ return parent
228
+ }
229
+ parent = parent.parent
230
+ }
231
+
232
+ // Fall back to the activity's content view
216
233
  try {
217
- val activity = context as? android.app.Activity
234
+ val activity = getActivityFromContext()
218
235
  activity?.findViewById<ViewGroup>(android.R.id.content)?.let { return it }
219
236
  } catch (e: Exception) {
220
- logDebug("Could not access activity content view: ${e.message}")
237
+ logDebug("Could not access activity root view: ${e.message}")
221
238
  }
239
+
222
240
  return this.parent as? ViewGroup
223
241
  }
224
242
 
243
+ /**
244
+ * Resolves an Activity from the view's context.
245
+ * Priority: ReactContext.currentActivity > ContextWrapper unwrap chain.
246
+ */
247
+ private fun getActivityFromContext(): Activity? {
248
+ (context as? ReactContext)?.currentActivity?.let { return it }
249
+
250
+ var ctx: Context? = context
251
+ while (ctx != null) {
252
+ if (ctx is Activity) return ctx
253
+ ctx = (ctx as? ContextWrapper)?.baseContext
254
+ }
255
+ return null
256
+ }
257
+
225
258
  /**
226
259
  * Initialize the blur view with current settings.
227
260
  * Called after the view is attached and the blur root has been swapped.
@@ -207,10 +207,13 @@ class ReactNativeProgressiveBlurView : FrameLayout {
207
207
 
208
208
  /**
209
209
  * Finds the optimal view to use as blur capture root.
210
- * Priority: nearest react-native-screens Screen > android.R.id.content > parent
210
+ * Priority: nearest react-native-screens Screen > android.R.id.content in parent chain > activity content > parent
211
+ *
212
+ * This handles both regular screens and modals — modals have their own window/view tree,
213
+ * so we walk up the parent chain for android.R.id.content before falling back to the activity.
211
214
  */
212
215
  private fun findOptimalBlurRoot(): ViewGroup? {
213
- return findNearestScreenAncestor() ?: getContentViewFallback()
216
+ return findNearestScreenAncestor() ?: getAppRootFallback()
214
217
  }
215
218
 
216
219
  /**
@@ -228,16 +231,27 @@ class ReactNativeProgressiveBlurView : FrameLayout {
228
231
  }
229
232
 
230
233
  /**
231
- * Falls back to android.R.id.content or the activity root view.
232
- * Tries ReactContext.currentActivity first, then unwraps ContextWrapper chain.
234
+ * Walks up the view parent chain looking for android.R.id.content (works in modals
235
+ * which have their own content root), then falls back to the activity's content view.
233
236
  */
234
- private fun getContentViewFallback(): ViewGroup? {
237
+ private fun getAppRootFallback(): ViewGroup? {
238
+ // Walk up the parent chain — catches modals which have their own android.R.id.content
239
+ var parent = this.parent
240
+ while (parent != null) {
241
+ if (parent is ViewGroup && parent.id == android.R.id.content) {
242
+ return parent
243
+ }
244
+ parent = parent.parent
245
+ }
246
+
247
+ // Fall back to the activity's content view
235
248
  try {
236
249
  val activity = getActivityFromContext()
237
250
  activity?.findViewById<ViewGroup>(android.R.id.content)?.let { return it }
238
251
  } catch (e: Exception) {
239
- logDebug("Could not access activity content view: ${e.message}")
252
+ logDebug("Could not access activity root view: ${e.message}")
240
253
  }
254
+
241
255
  return this.parent as? ViewGroup
242
256
  }
243
257
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sbaiahmed1/react-native-blur",
3
- "version": "4.5.5-beta.4",
3
+ "version": "4.5.5-beta.5",
4
4
  "description": "React native modern blur view",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",