@sbaiahmed1/react-native-blur 3.2.0 → 4.0.1
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.
- package/README.md +319 -309
- package/ReactNativeBlur.podspec +1 -1
- package/android/build.gradle +2 -3
- package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurView.kt +62 -269
- package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurViewManager.kt +9 -9
- package/ios/Helpers/BlurStyleHelpers.swift +1 -1
- package/ios/Helpers/ReactNativeBlurViewHelper.swift +6 -35
- package/ios/Helpers/ReactNativeLiquidGlassViewHelper.swift +44 -0
- package/ios/ReactNativeBlurView.mm +8 -61
- package/ios/{ReactNativeBlurViewManager.m → ReactNativeBlurViewManager.mm} +5 -35
- package/ios/ReactNativeLiquidGlassView.h +14 -0
- package/ios/ReactNativeLiquidGlassView.mm +291 -0
- package/ios/ReactNativeLiquidGlassViewManager.h +6 -0
- package/ios/ReactNativeLiquidGlassViewManager.mm +20 -0
- package/ios/Views/AdvancedBlurView.swift +5 -40
- package/ios/Views/BasicColoredView.swift +6 -50
- package/ios/Views/LiquidGlassContainerView.swift +151 -0
- package/lib/module/BlurView.js +16 -33
- package/lib/module/BlurView.js.map +1 -1
- package/lib/module/LiquidGlassView.js +75 -0
- package/lib/module/LiquidGlassView.js.map +1 -0
- package/lib/module/ReactNativeBlurViewNativeComponent.ts +0 -7
- package/lib/module/ReactNativeLiquidGlassViewNativeComponent.ts +57 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/BlurView.d.ts +19 -45
- package/lib/typescript/src/BlurView.d.ts.map +1 -1
- package/lib/typescript/src/LiquidGlassView.d.ts +85 -0
- package/lib/typescript/src/LiquidGlassView.d.ts.map +1 -0
- package/lib/typescript/src/ReactNativeBlurViewNativeComponent.d.ts +0 -6
- package/lib/typescript/src/ReactNativeBlurViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/ReactNativeLiquidGlassViewNativeComponent.d.ts +44 -0
- package/lib/typescript/src/ReactNativeLiquidGlassViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/BlurView.tsx +36 -77
- package/src/LiquidGlassView.tsx +138 -0
- package/src/ReactNativeBlurViewNativeComponent.ts +0 -7
- package/src/ReactNativeLiquidGlassViewNativeComponent.ts +57 -0
- package/src/index.tsx +6 -0
package/ReactNativeBlur.podspec
CHANGED
package/android/build.gradle
CHANGED
|
@@ -9,13 +9,12 @@ buildscript {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
dependencies {
|
|
12
|
-
classpath "com.android.tools.build:gradle:8.
|
|
12
|
+
classpath "com.android.tools.build:gradle:8.9.1"
|
|
13
13
|
// noinspection DifferentKotlinGradleVersion
|
|
14
14
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
apply plugin: "com.android.library"
|
|
20
19
|
apply plugin: "kotlin-android"
|
|
21
20
|
|
|
@@ -75,7 +74,7 @@ def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
|
75
74
|
dependencies {
|
|
76
75
|
implementation "com.facebook.react:react-android"
|
|
77
76
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
78
|
-
implementation 'com.
|
|
77
|
+
implementation 'com.qmdeve:QmBlurView:1.0.4.3'
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
react {
|
|
@@ -2,25 +2,22 @@ package com.sbaiahmed1.reactnativeblur
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
4
|
import android.graphics.Color
|
|
5
|
-
import android.graphics.drawable.ColorDrawable
|
|
6
|
-
import android.os.Build
|
|
7
5
|
import android.util.AttributeSet
|
|
8
6
|
import android.util.Log
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import eightbitlab.com.blurview.RenderEffectBlur
|
|
12
|
-
import eightbitlab.com.blurview.RenderScriptBlur
|
|
7
|
+
import com.qmdeve.blurview.widget.BlurView
|
|
8
|
+
import androidx.core.graphics.toColorInt
|
|
13
9
|
|
|
14
10
|
/**
|
|
15
11
|
* Android implementation of React Native BlurView component.
|
|
16
|
-
* Provides cross-platform blur effects using the
|
|
12
|
+
* Provides cross-platform blur effects using the QmBlurView library.
|
|
13
|
+
*
|
|
14
|
+
* QmBlurView is a high-performance blur library that uses native blur algorithms
|
|
15
|
+
* implemented with underlying Native calls for optimal performance.
|
|
17
16
|
*/
|
|
18
17
|
class ReactNativeBlurView : BlurView {
|
|
19
|
-
private var
|
|
20
|
-
private var
|
|
21
|
-
private var
|
|
22
|
-
private var isConfigured = false
|
|
23
|
-
private var pendingStyleUpdate: Boolean = false
|
|
18
|
+
private var currentBlurRadius = DEFAULT_BLUR_RADIUS
|
|
19
|
+
private var currentOverlayColor = Color.TRANSPARENT
|
|
20
|
+
private var currentCornerRadius = 0f
|
|
24
21
|
private var originalBackgroundColor: Int? = null
|
|
25
22
|
private var hasExplicitBackground: Boolean = false
|
|
26
23
|
private var glassTintColor: Int = Color.TRANSPARENT
|
|
@@ -30,7 +27,6 @@ class ReactNativeBlurView : BlurView {
|
|
|
30
27
|
|
|
31
28
|
companion object {
|
|
32
29
|
private const val TAG = "ReactNativeBlurView"
|
|
33
|
-
private const val MIN_BLUR_RADIUS = 0f
|
|
34
30
|
private const val MAX_BLUR_RADIUS = 25f
|
|
35
31
|
private const val DEFAULT_BLUR_RADIUS = 10f
|
|
36
32
|
private const val DEBUG = false // Set to true for debug builds
|
|
@@ -38,7 +34,6 @@ class ReactNativeBlurView : BlurView {
|
|
|
38
34
|
// Cross-platform blur amount constants
|
|
39
35
|
private const val MIN_BLUR_AMOUNT = 0f
|
|
40
36
|
private const val MAX_BLUR_AMOUNT = 100f
|
|
41
|
-
private const val DEFAULT_BLUR_AMOUNT = 10f
|
|
42
37
|
|
|
43
38
|
private fun logDebug(message: String) {
|
|
44
39
|
if (DEBUG) {
|
|
@@ -66,7 +61,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
66
61
|
}
|
|
67
62
|
}
|
|
68
63
|
|
|
69
|
-
constructor(context: Context?) : super(context) {
|
|
64
|
+
constructor(context: Context?) : super(context, null) {
|
|
70
65
|
initializeBlur()
|
|
71
66
|
}
|
|
72
67
|
|
|
@@ -74,30 +69,33 @@ class ReactNativeBlurView : BlurView {
|
|
|
74
69
|
initializeBlur()
|
|
75
70
|
}
|
|
76
71
|
|
|
77
|
-
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
|
78
|
-
context,
|
|
79
|
-
attrs,
|
|
80
|
-
defStyleAttr
|
|
81
|
-
) {
|
|
82
|
-
initializeBlur()
|
|
83
|
-
}
|
|
84
|
-
|
|
85
72
|
/**
|
|
86
73
|
* Initialize the blur view with default settings.
|
|
87
|
-
*
|
|
74
|
+
* QmBlurView automatically handles blur rendering without needing setupWith() calls.
|
|
88
75
|
*/
|
|
89
76
|
private fun initializeBlur() {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
77
|
+
try {
|
|
78
|
+
// Set initial blur properties using QmBlurView's API
|
|
79
|
+
// setBlurRadius takes Float, setOverlayColor takes Int, setCornerRadius takes Float (in dp)
|
|
80
|
+
super.setBlurRadius(currentBlurRadius)
|
|
81
|
+
super.setOverlayColor(currentOverlayColor)
|
|
82
|
+
super.setCornerRadius(currentCornerRadius)
|
|
83
|
+
|
|
84
|
+
// Set transparent background to prevent visual artifacts
|
|
85
|
+
super.setBackgroundColor(Color.TRANSPARENT)
|
|
86
|
+
|
|
87
|
+
logDebug("QmBlurView initialized with blurRadius: $currentBlurRadius, overlayColor: $currentOverlayColor")
|
|
88
|
+
} catch (e: Exception) {
|
|
89
|
+
logError("Failed to initialize blur view: ${e.message}", e)
|
|
90
|
+
}
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
/**
|
|
96
|
-
* Override setBackgroundColor to handle
|
|
94
|
+
* Override setBackgroundColor to handle background preservation.
|
|
97
95
|
* @param color The background color to apply
|
|
98
96
|
*/
|
|
99
97
|
override fun setBackgroundColor(color: Int) {
|
|
100
|
-
logDebug("setBackgroundColor called: $color
|
|
98
|
+
logDebug("setBackgroundColor called: $color")
|
|
101
99
|
|
|
102
100
|
// Store the original background color if it's not transparent
|
|
103
101
|
if (color != Color.TRANSPARENT) {
|
|
@@ -106,236 +104,34 @@ class ReactNativeBlurView : BlurView {
|
|
|
106
104
|
logDebug("Stored explicit background color: $color")
|
|
107
105
|
}
|
|
108
106
|
|
|
109
|
-
//
|
|
110
|
-
if (
|
|
111
|
-
logDebug("
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
logDebug("Attempting deferred blur setup from setBackgroundColor")
|
|
117
|
-
setupBlurView()
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// If blur is setup and we have an explicit background, apply it carefully
|
|
124
|
-
if (hasExplicitBackground && color != Color.TRANSPARENT) {
|
|
125
|
-
logDebug("Applying background color over blur: $color")
|
|
126
|
-
super.setBackgroundColor(color)
|
|
127
|
-
} else {
|
|
128
|
-
logDebug("Keeping transparent background for blur effect")
|
|
129
|
-
super.setBackgroundColor(Color.TRANSPARENT)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Override setAlpha to handle blur setup timing.
|
|
135
|
-
* @param alpha The alpha value to apply
|
|
136
|
-
*/
|
|
137
|
-
override fun setAlpha(alpha: Float) {
|
|
138
|
-
logDebug("setAlpha called: $alpha (isSetup: $isSetup)")
|
|
139
|
-
|
|
140
|
-
// Always apply alpha changes immediately as they don't interfere with blur setup
|
|
141
|
-
super.setAlpha(alpha)
|
|
142
|
-
|
|
143
|
-
// If blur is not setup yet, trigger setup attempt
|
|
144
|
-
if (!isSetup && isAttachedToWindow) {
|
|
145
|
-
pendingStyleUpdate = true
|
|
146
|
-
post {
|
|
147
|
-
if (!isSetup && isAttachedToWindow) {
|
|
148
|
-
logDebug("Attempting deferred blur setup from setAlpha")
|
|
149
|
-
setupBlurView()
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Override setElevation to handle blur setup timing.
|
|
157
|
-
* @param elevation The elevation value to apply
|
|
158
|
-
*/
|
|
159
|
-
override fun setElevation(elevation: Float) {
|
|
160
|
-
logDebug("setElevation called: $elevation (isSetup: $isSetup)")
|
|
161
|
-
|
|
162
|
-
// Always apply elevation changes immediately
|
|
163
|
-
super.setElevation(elevation)
|
|
164
|
-
|
|
165
|
-
// If blur is not setup yet, trigger setup attempt
|
|
166
|
-
if (!isSetup && isAttachedToWindow) {
|
|
167
|
-
pendingStyleUpdate = true
|
|
168
|
-
post {
|
|
169
|
-
if (!isSetup && isAttachedToWindow) {
|
|
170
|
-
logDebug("Attempting deferred blur setup from setElevation")
|
|
171
|
-
setupBlurView()
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Called when the view is attached to a window.
|
|
179
|
-
* Triggers blur setup if not already configured.
|
|
180
|
-
*/
|
|
181
|
-
override fun onAttachedToWindow() {
|
|
182
|
-
super.onAttachedToWindow()
|
|
183
|
-
|
|
184
|
-
// Now we can safely walk the parent hierarchy
|
|
185
|
-
if (!this.isConfigured) {
|
|
186
|
-
this.isConfigured = true
|
|
187
|
-
setupBlurView()
|
|
107
|
+
// Apply background color over blur if explicitly set
|
|
108
|
+
if (hasExplicitBackground && color != Color.TRANSPARENT) {
|
|
109
|
+
logDebug("Applying background color over blur: $color")
|
|
110
|
+
super.setBackgroundColor(color)
|
|
111
|
+
} else {
|
|
112
|
+
logDebug("Keeping transparent background for blur effect")
|
|
113
|
+
super.setBackgroundColor(Color.TRANSPARENT)
|
|
188
114
|
}
|
|
189
115
|
}
|
|
190
116
|
|
|
191
117
|
/**
|
|
192
118
|
* Called when the view is detached from a window.
|
|
193
|
-
* Performs cleanup to prevent memory leaks
|
|
119
|
+
* Performs cleanup to prevent memory leaks.
|
|
194
120
|
*/
|
|
195
121
|
override fun onDetachedFromWindow() {
|
|
196
122
|
super.onDetachedFromWindow()
|
|
197
|
-
|
|
198
|
-
this.isConfigured = false
|
|
199
|
-
this.removeCallbacks(null)
|
|
200
123
|
cleanup()
|
|
201
124
|
}
|
|
202
125
|
|
|
203
126
|
/**
|
|
204
|
-
* Cleanup method to reset state
|
|
127
|
+
* Cleanup method to reset state.
|
|
205
128
|
* Helps prevent memory leaks and ensures clean state.
|
|
206
129
|
*/
|
|
207
130
|
fun cleanup() {
|
|
208
|
-
isSetup = false
|
|
209
131
|
hasExplicitBackground = false
|
|
210
132
|
originalBackgroundColor = null
|
|
211
|
-
pendingStyleUpdate = false
|
|
212
|
-
// Clear any pending runnables to prevent memory leaks
|
|
213
133
|
removeCallbacks(null)
|
|
214
|
-
logDebug("View
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Setup the blur view with multiple fallback strategies for finding the root view.
|
|
219
|
-
* Uses RenderEffectBlur for optimal performance on modern Android versions.
|
|
220
|
-
*/
|
|
221
|
-
private fun setupBlurView() {
|
|
222
|
-
if (isSetup) return
|
|
223
|
-
|
|
224
|
-
try {
|
|
225
|
-
val rootView = findOptimalBlurRoot()
|
|
226
|
-
|
|
227
|
-
rootView?.let { root ->
|
|
228
|
-
try {
|
|
229
|
-
// Choose blur algorithm based on Android API level
|
|
230
|
-
val blurAlgorithm = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
231
|
-
// Android 12+ (API 31+): Use RenderEffectBlur for better performance
|
|
232
|
-
logDebug("Using RenderEffectBlur for API ${Build.VERSION.SDK_INT}")
|
|
233
|
-
RenderEffectBlur()
|
|
234
|
-
} else {
|
|
235
|
-
// Android 10-11 (API < 31): Use RenderScriptBlur for compatibility
|
|
236
|
-
logDebug("Using RenderScriptBlur for API ${Build.VERSION.SDK_INT}")
|
|
237
|
-
try {
|
|
238
|
-
RenderScriptBlur(context)
|
|
239
|
-
} catch (e: Exception) {
|
|
240
|
-
logWarning("RenderScriptBlur not supported on this device: ${e.message}")
|
|
241
|
-
// Fallback: return null to trigger transparent background fallback
|
|
242
|
-
throw UnsupportedOperationException("Blur not supported on this device", e)
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Setup the blur view with the appropriate algorithm
|
|
247
|
-
this.setupWith(root, blurAlgorithm)
|
|
248
|
-
.setBlurRadius(blurRadius)
|
|
249
|
-
.setOverlayColor(overlayColor)
|
|
250
|
-
|
|
251
|
-
isSetup = true
|
|
252
|
-
pendingStyleUpdate = false
|
|
253
|
-
|
|
254
|
-
// Apply any pending background color after blur setup
|
|
255
|
-
if (hasExplicitBackground && originalBackgroundColor != null) {
|
|
256
|
-
logDebug("Applying pending background color: $originalBackgroundColor")
|
|
257
|
-
super.setBackgroundColor(originalBackgroundColor!!)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
logDebug("Blur setup successful with root: ${root.javaClass.simpleName}")
|
|
261
|
-
} catch (e: Exception) {
|
|
262
|
-
logWarning("Failed to setup blur algorithm: ${e.message}")
|
|
263
|
-
// Fallback: use semi-transparent overlay when blur is unsupported
|
|
264
|
-
super.setBackgroundColor(overlayColor)
|
|
265
|
-
isSetup = true // Mark as setup to prevent retry loops
|
|
266
|
-
}
|
|
267
|
-
} ?: run {
|
|
268
|
-
logWarning("No suitable root view found for blur setup")
|
|
269
|
-
// Use semi-transparent overlay when no root view is available
|
|
270
|
-
super.setBackgroundColor(overlayColor)
|
|
271
|
-
isSetup = true
|
|
272
|
-
}
|
|
273
|
-
} catch (e: Exception) {
|
|
274
|
-
// Final fallback: set transparent background to prevent visual artifacts
|
|
275
|
-
super.setBackgroundColor(overlayColor)
|
|
276
|
-
logError("Failed to setup blur: ${e.message}", e)
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Find the optimal blur root view by walking up the parent hierarchy.
|
|
282
|
-
* This method is crucial for proper blur rendering during navigation transitions.
|
|
283
|
-
* @return The optimal ViewGroup to use as blur root or null if not found
|
|
284
|
-
*/
|
|
285
|
-
private fun findOptimalBlurRoot(): ViewGroup? {
|
|
286
|
-
var current = this.parent
|
|
287
|
-
|
|
288
|
-
// Walk up the parent hierarchy to find the best blur root
|
|
289
|
-
while (current != null) {
|
|
290
|
-
if (current is ViewGroup) {
|
|
291
|
-
// Prefer content view as it's the most stable during transitions
|
|
292
|
-
if (current.id == android.R.id.content) {
|
|
293
|
-
return current
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Look for other suitable container views
|
|
297
|
-
val className = current.javaClass.simpleName
|
|
298
|
-
if (className.contains("DecorView") ||
|
|
299
|
-
className.contains("ContentFrameLayout") ||
|
|
300
|
-
(className.contains("LinearLayout") && current.parent == null)) {
|
|
301
|
-
// For LinearLayout, only consider it if it's the root of the hierarchy (parent == null)
|
|
302
|
-
// This avoids misidentifying containers in complex layouts
|
|
303
|
-
return current
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
current = current.parent
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Fallback: try to get activity's content view
|
|
310
|
-
return findRootView()
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Find the root view using multiple strategies.
|
|
315
|
-
* @return The root ViewGroup or null if not found
|
|
316
|
-
*/
|
|
317
|
-
private fun findRootView(): ViewGroup? {
|
|
318
|
-
// Strategy 1: Look for the content view (most reliable)
|
|
319
|
-
var parent = this.parent
|
|
320
|
-
while (parent != null) {
|
|
321
|
-
if (parent is ViewGroup && parent.id == android.R.id.content) {
|
|
322
|
-
return parent
|
|
323
|
-
}
|
|
324
|
-
parent = parent.parent
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// Strategy 2: If content view not found, use the activity's root view
|
|
328
|
-
try {
|
|
329
|
-
val activity = context as? android.app.Activity
|
|
330
|
-
activity?.findViewById<ViewGroup>(android.R.id.content)?.let {
|
|
331
|
-
return it
|
|
332
|
-
}
|
|
333
|
-
} catch (e: Exception) {
|
|
334
|
-
logDebug("Could not access activity root view: ${e.message}")
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Strategy 3: Fallback to immediate parent
|
|
338
|
-
return this.parent as? ViewGroup
|
|
134
|
+
logDebug("View cleaned up")
|
|
339
135
|
}
|
|
340
136
|
|
|
341
137
|
/**
|
|
@@ -343,15 +139,14 @@ class ReactNativeBlurView : BlurView {
|
|
|
343
139
|
* @param amount The blur amount value (0-100), will be mapped to Android's 0-25 radius range
|
|
344
140
|
*/
|
|
345
141
|
fun setBlurAmount(amount: Float) {
|
|
346
|
-
|
|
347
|
-
logDebug("setBlurAmount: $amount -> $
|
|
142
|
+
currentBlurRadius = mapBlurAmountToRadius(amount)
|
|
143
|
+
logDebug("setBlurAmount: $amount -> $currentBlurRadius (mapped from 0-100 to 0-25 range)")
|
|
348
144
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
145
|
+
try {
|
|
146
|
+
// QmBlurView uses setBlurRadius() to set blur intensity
|
|
147
|
+
super.setBlurRadius(currentBlurRadius)
|
|
148
|
+
} catch (e: Exception) {
|
|
149
|
+
logError("Failed to set blur radius: ${e.message}", e)
|
|
355
150
|
}
|
|
356
151
|
}
|
|
357
152
|
|
|
@@ -401,15 +196,14 @@ class ReactNativeBlurView : BlurView {
|
|
|
401
196
|
*/
|
|
402
197
|
fun setBlurType(type: String) {
|
|
403
198
|
val blurType = BlurType.fromString(type)
|
|
404
|
-
|
|
405
|
-
logDebug("setBlurType: $type -> ${blurType.name}
|
|
199
|
+
currentOverlayColor = blurType.overlayColor
|
|
200
|
+
logDebug("setBlurType: $type -> ${blurType.name}")
|
|
406
201
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
202
|
+
try {
|
|
203
|
+
// QmBlurView uses setOverlayColor() to set the tint/overlay color
|
|
204
|
+
super.setOverlayColor(currentOverlayColor)
|
|
205
|
+
} catch (e: Exception) {
|
|
206
|
+
logError("Failed to set overlay color: ${e.message}", e)
|
|
413
207
|
}
|
|
414
208
|
}
|
|
415
209
|
|
|
@@ -420,7 +214,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
420
214
|
fun setReducedTransparencyFallbackColor(color: String?) {
|
|
421
215
|
color?.let {
|
|
422
216
|
try {
|
|
423
|
-
val fallbackColor =
|
|
217
|
+
val fallbackColor = it.toColorInt()
|
|
424
218
|
logDebug("setReducedTransparencyFallbackColor: $color -> $fallbackColor (stored but not applied unless accessibility requires it)")
|
|
425
219
|
|
|
426
220
|
// Store the fallback color but don't apply it unless accessibility settings require it
|
|
@@ -443,7 +237,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
443
237
|
fun setGlassTintColor(color: String?) {
|
|
444
238
|
color?.let {
|
|
445
239
|
try {
|
|
446
|
-
glassTintColor =
|
|
240
|
+
glassTintColor = it.toColorInt()
|
|
447
241
|
logDebug("setGlassTintColor: $color -> $glassTintColor")
|
|
448
242
|
updateGlassEffect()
|
|
449
243
|
} catch (e: Exception) {
|
|
@@ -476,10 +270,10 @@ class ReactNativeBlurView : BlurView {
|
|
|
476
270
|
logDebug("setType: $type")
|
|
477
271
|
updateViewType()
|
|
478
272
|
}
|
|
479
|
-
|
|
273
|
+
|
|
480
274
|
/**
|
|
481
275
|
* Set the view type (blur or liquidGlass).
|
|
482
|
-
* @param
|
|
276
|
+
* @param isInteractive The view type string
|
|
483
277
|
*/
|
|
484
278
|
fun setIsInteractive(isInteractive: Boolean) {
|
|
485
279
|
logDebug("setType: $isInteractive")
|
|
@@ -499,7 +293,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
499
293
|
* Update the glass effect based on current glass properties.
|
|
500
294
|
*/
|
|
501
295
|
private fun updateGlassEffect() {
|
|
502
|
-
if (viewType == "liquidGlass"
|
|
296
|
+
if (viewType == "liquidGlass") {
|
|
503
297
|
try {
|
|
504
298
|
// Apply glass tint with opacity
|
|
505
299
|
val glassColor = Color.argb(
|
|
@@ -508,7 +302,8 @@ class ReactNativeBlurView : BlurView {
|
|
|
508
302
|
Color.green(glassTintColor),
|
|
509
303
|
Color.blue(glassTintColor)
|
|
510
304
|
)
|
|
511
|
-
setOverlayColor
|
|
305
|
+
// Use QmBlurView's setOverlayColor method
|
|
306
|
+
super.setOverlayColor(glassColor)
|
|
512
307
|
logDebug("Applied glass effect: color=$glassColor, opacity=$glassOpacity")
|
|
513
308
|
} catch (e: Exception) {
|
|
514
309
|
logError("Failed to update glass effect: ${e.message}", e)
|
|
@@ -526,12 +321,10 @@ class ReactNativeBlurView : BlurView {
|
|
|
526
321
|
}
|
|
527
322
|
"blur" -> {
|
|
528
323
|
// Restore original blur overlay color
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
logError("Failed to restore blur overlay: ${e.message}", e)
|
|
534
|
-
}
|
|
324
|
+
try {
|
|
325
|
+
super.setOverlayColor(currentOverlayColor)
|
|
326
|
+
} catch (e: Exception) {
|
|
327
|
+
logError("Failed to restore blur overlay: ${e.message}", e)
|
|
535
328
|
}
|
|
536
329
|
}
|
|
537
330
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
package com.sbaiahmed1.reactnativeblur
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
-
import com.facebook.react.uimanager.
|
|
4
|
+
import com.facebook.react.uimanager.SimpleViewManager
|
|
5
5
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
6
|
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
7
7
|
import com.facebook.react.uimanager.annotations.ReactProp
|
|
@@ -9,7 +9,7 @@ import com.facebook.react.viewmanagers.ReactNativeBlurViewManagerInterface
|
|
|
9
9
|
import com.facebook.react.viewmanagers.ReactNativeBlurViewManagerDelegate
|
|
10
10
|
|
|
11
11
|
@ReactModule(name = ReactNativeBlurViewManager.NAME)
|
|
12
|
-
class ReactNativeBlurViewManager :
|
|
12
|
+
class ReactNativeBlurViewManager : SimpleViewManager<ReactNativeBlurView>(),
|
|
13
13
|
ReactNativeBlurViewManagerInterface<ReactNativeBlurView> {
|
|
14
14
|
private val mDelegate: ViewManagerDelegate<ReactNativeBlurView>
|
|
15
15
|
|
|
@@ -45,32 +45,32 @@ class ReactNativeBlurViewManager : ViewGroupManager<ReactNativeBlurView>(),
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
@ReactProp(name = "glassTintColor")
|
|
48
|
-
|
|
48
|
+
fun setGlassTintColor(view: ReactNativeBlurView?, glassTintColor: String?) {
|
|
49
49
|
view?.setGlassTintColor(glassTintColor)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
@ReactProp(name = "glassOpacity")
|
|
53
|
-
|
|
53
|
+
fun setGlassOpacity(view: ReactNativeBlurView?, glassOpacity: Double) {
|
|
54
54
|
view?.setGlassOpacity(glassOpacity.toFloat())
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
@ReactProp(name = "type")
|
|
58
|
-
|
|
58
|
+
fun setType(view: ReactNativeBlurView?, type: String?) {
|
|
59
59
|
view?.setType(type ?: "blur")
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
@ReactProp(name = "glassType")
|
|
63
|
-
|
|
63
|
+
fun setGlassType(view: ReactNativeBlurView?, glassType: String?) {
|
|
64
64
|
view?.setGlassType(glassType ?: "clear")
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
@ReactProp(name = "isInteractive")
|
|
68
|
-
|
|
68
|
+
fun setIsInteractive(view: ReactNativeBlurView?, isInteractive: Boolean) {
|
|
69
69
|
view?.setIsInteractive(isInteractive)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
@ReactProp(name = "
|
|
73
|
-
override fun setIgnoreSafeArea(view: ReactNativeBlurView?,
|
|
72
|
+
@ReactProp(name = "ignoreSafeArea")
|
|
73
|
+
override fun setIgnoreSafeArea(view: ReactNativeBlurView?, ignoreSafeArea: Boolean) {
|
|
74
74
|
// no-op
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -7,21 +7,11 @@ import UIKit
|
|
|
7
7
|
|
|
8
8
|
@objc public class ReactNativeBlurViewHelper: NSObject {
|
|
9
9
|
|
|
10
|
-
/// Creates and returns a view
|
|
10
|
+
/// Creates and returns a blur view.
|
|
11
11
|
@objc public static func createBlurViewWithFrame(_ frame: CGRect) -> AdvancedBlurView {
|
|
12
12
|
return AdvancedBlurView(frame: frame)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
/// Updates the blur view with a new glass tint color.
|
|
16
|
-
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withGlassTintColor glassTintColor: UIColor) {
|
|
17
|
-
blurView.glassTintColor = glassTintColor
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/// Updates the blur view with a new glass opacity.
|
|
21
|
-
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withGlassOpacity glassOpacity: Double) {
|
|
22
|
-
blurView.glassOpacity = glassOpacity
|
|
23
|
-
}
|
|
24
|
-
|
|
25
15
|
/// Updates the blur view with a new blur amount.
|
|
26
16
|
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withBlurAmount blurAmount: Double) {
|
|
27
17
|
blurView.blurAmount = blurAmount
|
|
@@ -32,33 +22,14 @@ import UIKit
|
|
|
32
22
|
blurView.blurTypeString = blurType
|
|
33
23
|
}
|
|
34
24
|
|
|
35
|
-
/// Updates the blur view with a new
|
|
36
|
-
@objc public static func updateBlurView(_ blurView: AdvancedBlurView,
|
|
37
|
-
blurView.
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/// Updates the blur view with a new blur style.
|
|
41
|
-
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withType type: String) {
|
|
42
|
-
blurView.type = type
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/// Updates the blur view with a new blur style.
|
|
46
|
-
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withIsInteractive isInteractive: Bool) {
|
|
47
|
-
blurView.isInteractive = isInteractive
|
|
25
|
+
/// Updates the blur view with a new reduced transparency fallback color.
|
|
26
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withReducedTransparencyFallbackColor reducedTransparencyFallbackColor: UIColor) {
|
|
27
|
+
blurView.reducedTransparencyFallbackColor = reducedTransparencyFallbackColor
|
|
48
28
|
}
|
|
49
29
|
|
|
50
|
-
/// Updates the blur view with a new
|
|
30
|
+
/// Updates the blur view with a new ignoreSafeArea value.
|
|
51
31
|
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withIgnoringSafeArea ignoreSafeArea: Bool) {
|
|
52
32
|
blurView.ignoreSafeArea = ignoreSafeArea
|
|
53
33
|
}
|
|
54
|
-
|
|
55
|
-
/// Updates the blur view with a new reduced transparency fallback color.
|
|
56
|
-
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withReducedTransparencyFallbackColor fallbackColor: UIColor) {
|
|
57
|
-
blurView.reducedTransparencyFallbackColor = fallbackColor
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/// No-op updater kept for API compatibility.
|
|
61
|
-
@objc public static func updateBlurView(_ blurView: AdvancedBlurView) {
|
|
62
|
-
// Nothing to update in the minimal implementation
|
|
63
|
-
}
|
|
64
34
|
}
|
|
35
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ReactNativeLiquidGlassViewHelper.swift
|
|
2
|
+
|
|
3
|
+
import SwiftUI
|
|
4
|
+
import UIKit
|
|
5
|
+
|
|
6
|
+
// MARK: - Objective-C Bridging Helpers for Liquid Glass
|
|
7
|
+
|
|
8
|
+
@objc public class ReactNativeLiquidGlassViewHelper: NSObject {
|
|
9
|
+
|
|
10
|
+
/// Creates and returns a liquid glass view container.
|
|
11
|
+
@objc public static func createLiquidGlassViewWithFrame(_ frame: CGRect) -> LiquidGlassContainerView {
|
|
12
|
+
return LiquidGlassContainerView(frame: frame)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/// Updates the liquid glass view with a new glass tint color.
|
|
16
|
+
@objc public static func updateLiquidGlassView(_ liquidGlassView: LiquidGlassContainerView, withGlassTintColor glassTintColor: UIColor) {
|
|
17
|
+
liquidGlassView.glassTintColor = glassTintColor
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/// Updates the liquid glass view with a new glass opacity.
|
|
21
|
+
@objc public static func updateLiquidGlassView(_ liquidGlassView: LiquidGlassContainerView, withGlassOpacity glassOpacity: Double) {
|
|
22
|
+
liquidGlassView.glassOpacity = glassOpacity
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// Updates the liquid glass view with a new glass type.
|
|
26
|
+
@objc public static func updateLiquidGlassView(_ liquidGlassView: LiquidGlassContainerView, withGlassType glassType: String) {
|
|
27
|
+
liquidGlassView.glassType = glassType
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/// Updates the liquid glass view with a new interactivity setting.
|
|
31
|
+
@objc public static func updateLiquidGlassView(_ liquidGlassView: LiquidGlassContainerView, withIsInteractive isInteractive: Bool) {
|
|
32
|
+
liquidGlassView.isInteractive = isInteractive
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// Updates the liquid glass view with a new safe area setting.
|
|
36
|
+
@objc public static func updateLiquidGlassView(_ liquidGlassView: LiquidGlassContainerView, withIgnoringSafeArea ignoreSafeArea: Bool) {
|
|
37
|
+
liquidGlassView.ignoreSafeArea = ignoreSafeArea
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// Updates the liquid glass view with a new reduced transparency fallback color.
|
|
41
|
+
@objc public static func updateLiquidGlassView(_ liquidGlassView: LiquidGlassContainerView, withReducedTransparencyFallbackColor reducedTransparencyFallbackColor: UIColor) {
|
|
42
|
+
liquidGlassView.reducedTransparencyFallbackColor = reducedTransparencyFallbackColor
|
|
43
|
+
}
|
|
44
|
+
}
|