react-native 0.86.0-rc.0 → 0.86.0-rc.2
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/Libraries/Components/Pressable/Pressable.d.ts +1 -0
- package/Libraries/Components/Pressable/useAndroidRippleForView.js +7 -8
- package/Libraries/Components/Touchable/TouchableNativeFeedback.js +6 -10
- package/Libraries/Components/View/ViewPropTypes.js +3 -1
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/React/Base/RCTVersion.m +1 -1
- package/ReactAndroid/api/ReactAndroid.api +1 -0
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.kt +59 -62
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactDrawableHelper.kt +59 -20
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.kt +30 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt +2 -7
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp +19 -2
- package/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/NativeDrawable.h +47 -16
- package/package.json +9 -9
- package/scripts/cocoapods/rncore.rb +65 -11
- package/scripts/cocoapods/rndependencies.rb +65 -11
- package/scripts/cocoapods/utils.rb +52 -0
- package/scripts/codegen/generate-artifacts-executor/generateReactCodegenPodspec.js +8 -3
- package/scripts/react_native_pods.rb +15 -2
- package/sdks/hermes-engine/hermes-utils.rb +92 -5
- package/types_generated/Libraries/Components/Pressable/useAndroidRippleForView.d.ts +5 -2
- package/types_generated/Libraries/Components/Touchable/TouchableNativeFeedback.d.ts +8 -6
- package/types_generated/Libraries/Components/View/ViewPropTypes.d.ts +4 -2
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type {ProcessedColorValue} from '../../StyleSheet/processColor';
|
|
11
12
|
import type {ColorValue} from '../../StyleSheet/StyleSheet';
|
|
12
13
|
import type {GestureResponderEvent} from '../../Types/CoreEventTypes';
|
|
13
14
|
|
|
@@ -15,15 +16,15 @@ import processColor from '../../StyleSheet/processColor';
|
|
|
15
16
|
import Platform from '../../Utilities/Platform';
|
|
16
17
|
import View from '../View/View';
|
|
17
18
|
import {Commands} from '../View/ViewNativeComponent';
|
|
18
|
-
import invariant from 'invariant';
|
|
19
19
|
import * as React from 'react';
|
|
20
20
|
import {useMemo} from 'react';
|
|
21
21
|
|
|
22
22
|
type NativeBackgroundProp = Readonly<{
|
|
23
23
|
type: 'RippleAndroid',
|
|
24
|
-
color: ?
|
|
24
|
+
color: ?ProcessedColorValue,
|
|
25
25
|
borderless: boolean,
|
|
26
26
|
rippleRadius: ?number,
|
|
27
|
+
alpha: ?number,
|
|
27
28
|
}>;
|
|
28
29
|
|
|
29
30
|
export type PressableAndroidRippleConfig = {
|
|
@@ -31,6 +32,7 @@ export type PressableAndroidRippleConfig = {
|
|
|
31
32
|
borderless?: boolean,
|
|
32
33
|
radius?: number,
|
|
33
34
|
foreground?: boolean,
|
|
35
|
+
alpha?: number,
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
/**
|
|
@@ -48,7 +50,7 @@ export default function useAndroidRippleForView(
|
|
|
48
50
|
| Readonly<{nativeBackgroundAndroid: NativeBackgroundProp}>
|
|
49
51
|
| Readonly<{nativeForegroundAndroid: NativeBackgroundProp}>,
|
|
50
52
|
}> {
|
|
51
|
-
const {color, borderless, radius, foreground} = rippleConfig ?? {};
|
|
53
|
+
const {color, borderless, radius, foreground, alpha} = rippleConfig ?? {};
|
|
52
54
|
|
|
53
55
|
return useMemo(() => {
|
|
54
56
|
if (
|
|
@@ -56,16 +58,13 @@ export default function useAndroidRippleForView(
|
|
|
56
58
|
(color != null || borderless != null || radius != null)
|
|
57
59
|
) {
|
|
58
60
|
const processedColor = processColor(color);
|
|
59
|
-
invariant(
|
|
60
|
-
processedColor == null || typeof processedColor === 'number',
|
|
61
|
-
'Unexpected color given for Ripple color',
|
|
62
|
-
);
|
|
63
61
|
|
|
64
62
|
const nativeRippleValue = {
|
|
65
63
|
type: 'RippleAndroid',
|
|
66
64
|
color: processedColor,
|
|
67
65
|
borderless: borderless === true,
|
|
68
66
|
rippleRadius: radius,
|
|
67
|
+
alpha: alpha ?? null,
|
|
69
68
|
};
|
|
70
69
|
|
|
71
70
|
return {
|
|
@@ -105,5 +104,5 @@ export default function useAndroidRippleForView(
|
|
|
105
104
|
};
|
|
106
105
|
}
|
|
107
106
|
return null;
|
|
108
|
-
}, [borderless, color, foreground, radius, viewRef]);
|
|
107
|
+
}, [alpha, borderless, color, foreground, radius, viewRef]);
|
|
109
108
|
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type {ProcessedColorValue} from '../../StyleSheet/processColor';
|
|
12
|
+
import type {ColorValue} from '../../StyleSheet/StyleSheet';
|
|
11
13
|
import type {GestureResponderEvent} from '../../Types/CoreEventTypes';
|
|
12
14
|
import type {TouchableWithoutFeedbackProps} from './TouchableWithoutFeedback';
|
|
13
15
|
|
|
@@ -20,7 +22,6 @@ import {findHostInstance_DEPRECATED} from '../../ReactNative/RendererProxy';
|
|
|
20
22
|
import processColor from '../../StyleSheet/processColor';
|
|
21
23
|
import Platform from '../../Utilities/Platform';
|
|
22
24
|
import {Commands} from '../View/ViewNativeComponent';
|
|
23
|
-
import invariant from 'invariant';
|
|
24
25
|
import * as React from 'react';
|
|
25
26
|
import {cloneElement} from 'react';
|
|
26
27
|
|
|
@@ -96,7 +97,7 @@ export type TouchableNativeFeedbackProps = Readonly<{
|
|
|
96
97
|
}>
|
|
97
98
|
| Readonly<{
|
|
98
99
|
type: 'RippleAndroid',
|
|
99
|
-
color: ?
|
|
100
|
+
color: ?ProcessedColorValue,
|
|
100
101
|
borderless: boolean,
|
|
101
102
|
rippleRadius: ?number,
|
|
102
103
|
}>
|
|
@@ -177,23 +178,18 @@ class TouchableNativeFeedback extends React.Component<
|
|
|
177
178
|
* @param rippleRadius The radius of ripple effect
|
|
178
179
|
*/
|
|
179
180
|
static Ripple: (
|
|
180
|
-
color:
|
|
181
|
+
color: ColorValue,
|
|
181
182
|
borderless: boolean,
|
|
182
183
|
rippleRadius?: ?number,
|
|
183
184
|
) => Readonly<{
|
|
184
185
|
borderless: boolean,
|
|
185
|
-
color: ?
|
|
186
|
+
color: ?ProcessedColorValue,
|
|
186
187
|
rippleRadius: ?number,
|
|
187
188
|
type: 'RippleAndroid',
|
|
188
|
-
}> = (color:
|
|
189
|
+
}> = (color: ColorValue, borderless: boolean, rippleRadius?: ?number) => {
|
|
189
190
|
const processedColor = processColor(color);
|
|
190
|
-
invariant(
|
|
191
|
-
processedColor == null || typeof processedColor === 'number',
|
|
192
|
-
'Unexpected color given for Ripple color',
|
|
193
|
-
);
|
|
194
191
|
return {
|
|
195
192
|
type: 'RippleAndroid',
|
|
196
|
-
// $FlowFixMe[incompatible-type]
|
|
197
193
|
color: processedColor,
|
|
198
194
|
borderless,
|
|
199
195
|
rippleRadius,
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
import type {EdgeInsetsOrSizeProp} from '../../StyleSheet/EdgeInsetsPropType';
|
|
14
|
+
import type {ProcessedColorValue} from '../../StyleSheet/processColor';
|
|
14
15
|
import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
|
|
15
16
|
import type {
|
|
16
17
|
BlurEvent,
|
|
@@ -264,9 +265,10 @@ type AndroidDrawableThemeAttr = Readonly<{
|
|
|
264
265
|
|
|
265
266
|
type AndroidDrawableRipple = Readonly<{
|
|
266
267
|
type: 'RippleAndroid',
|
|
267
|
-
color?: ?
|
|
268
|
+
color?: ?ProcessedColorValue,
|
|
268
269
|
borderless?: ?boolean,
|
|
269
270
|
rippleRadius?: ?number,
|
|
271
|
+
alpha?: ?number,
|
|
270
272
|
}>;
|
|
271
273
|
|
|
272
274
|
type AndroidDrawable = AndroidDrawableThemeAttr | AndroidDrawableRipple;
|
|
@@ -29,7 +29,7 @@ export default class ReactNativeVersion {
|
|
|
29
29
|
static major: number = 0;
|
|
30
30
|
static minor: number = 86;
|
|
31
31
|
static patch: number = 0;
|
|
32
|
-
static prerelease: string | null = 'rc.
|
|
32
|
+
static prerelease: string | null = 'rc.2';
|
|
33
33
|
|
|
34
34
|
static getVersionString(): string {
|
|
35
35
|
return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -6468,6 +6468,7 @@ public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGro
|
|
|
6468
6468
|
public fun getZIndexMappedChildIndex (I)I
|
|
6469
6469
|
public fun hasOverlappingRendering ()Z
|
|
6470
6470
|
protected fun onAttachedToWindow ()V
|
|
6471
|
+
protected fun onConfigurationChanged (Landroid/content/res/Configuration;)V
|
|
6471
6472
|
public fun onHoverEvent (Landroid/view/MotionEvent;)Z
|
|
6472
6473
|
public fun onInterceptTouchEvent (Landroid/view/MotionEvent;)Z
|
|
6473
6474
|
protected fun onLayout (ZIIII)V
|
|
@@ -7,17 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
package com.facebook.react.modules.image
|
|
9
9
|
|
|
10
|
+
import android.media.ExifInterface
|
|
10
11
|
import android.net.Uri
|
|
11
12
|
import android.util.SparseArray
|
|
12
13
|
import com.facebook.common.executors.CallerThreadExecutor
|
|
14
|
+
import com.facebook.common.memory.PooledByteBuffer
|
|
13
15
|
import com.facebook.common.references.CloseableReference
|
|
14
16
|
import com.facebook.datasource.BaseDataSubscriber
|
|
15
17
|
import com.facebook.datasource.DataSource
|
|
16
18
|
import com.facebook.datasource.DataSubscriber
|
|
17
19
|
import com.facebook.drawee.backends.pipeline.Fresco
|
|
18
20
|
import com.facebook.fbreact.specs.NativeImageLoaderAndroidSpec
|
|
21
|
+
import com.facebook.imagepipeline.common.RotationOptions
|
|
19
22
|
import com.facebook.imagepipeline.core.ImagePipeline
|
|
20
|
-
import com.facebook.imagepipeline.image.
|
|
23
|
+
import com.facebook.imagepipeline.image.EncodedImage
|
|
21
24
|
import com.facebook.imagepipeline.request.ImageRequest
|
|
22
25
|
import com.facebook.imagepipeline.request.ImageRequestBuilder
|
|
23
26
|
import com.facebook.react.bridge.GuardedAsyncTask
|
|
@@ -82,39 +85,13 @@ internal class ImageLoaderModule : NativeImageLoaderAndroidSpec, LifecycleEventL
|
|
|
82
85
|
return
|
|
83
86
|
}
|
|
84
87
|
val source = ImageSource(reactApplicationContext, uriString)
|
|
85
|
-
val request: ImageRequest =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return
|
|
93
|
-
}
|
|
94
|
-
val ref = dataSource.result
|
|
95
|
-
if (ref != null) {
|
|
96
|
-
try {
|
|
97
|
-
val image: CloseableImage = ref.get()
|
|
98
|
-
val sizes = buildReadableMap {
|
|
99
|
-
put("width", image.width)
|
|
100
|
-
put("height", image.height)
|
|
101
|
-
}
|
|
102
|
-
promise.resolve(sizes)
|
|
103
|
-
} catch (e: Exception) {
|
|
104
|
-
promise.reject(ERROR_GET_SIZE_FAILURE, e)
|
|
105
|
-
} finally {
|
|
106
|
-
CloseableReference.closeSafely(ref)
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
promise.reject(ERROR_GET_SIZE_FAILURE, "Failed to get the size of the image")
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
|
|
114
|
-
promise.reject(ERROR_GET_SIZE_FAILURE, dataSource.failureCause)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
dataSource.subscribe(dataSubscriber, CallerThreadExecutor.getInstance())
|
|
88
|
+
val request: ImageRequest =
|
|
89
|
+
ImageRequestBuilder.newBuilderWithSource(source.uri)
|
|
90
|
+
.setRotationOptions(RotationOptions.disableRotation())
|
|
91
|
+
.build()
|
|
92
|
+
val dataSource: DataSource<CloseableReference<PooledByteBuffer>> =
|
|
93
|
+
this.imagePipeline.fetchEncodedImage(request, this.callerContext)
|
|
94
|
+
dataSource.subscribe(createSizeSubscriber(promise), CallerThreadExecutor.getInstance())
|
|
118
95
|
}
|
|
119
96
|
|
|
120
97
|
/**
|
|
@@ -134,41 +111,61 @@ internal class ImageLoaderModule : NativeImageLoaderAndroidSpec, LifecycleEventL
|
|
|
134
111
|
val source = ImageSource(reactApplicationContext, uriString)
|
|
135
112
|
val imageRequestBuilder: ImageRequestBuilder =
|
|
136
113
|
ImageRequestBuilder.newBuilderWithSource(source.uri)
|
|
114
|
+
.setRotationOptions(RotationOptions.disableRotation())
|
|
137
115
|
val request: ImageRequest =
|
|
138
116
|
ReactNetworkImageRequest.fromBuilderWithHeaders(imageRequestBuilder, headers)
|
|
139
|
-
val dataSource: DataSource<CloseableReference<
|
|
140
|
-
this.imagePipeline.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
117
|
+
val dataSource: DataSource<CloseableReference<PooledByteBuffer>> =
|
|
118
|
+
this.imagePipeline.fetchEncodedImage(request, this.callerContext)
|
|
119
|
+
dataSource.subscribe(createSizeSubscriber(promise), CallerThreadExecutor.getInstance())
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private fun createSizeSubscriber(
|
|
123
|
+
promise: Promise
|
|
124
|
+
): DataSubscriber<CloseableReference<PooledByteBuffer>> =
|
|
125
|
+
object : BaseDataSubscriber<CloseableReference<PooledByteBuffer>>() {
|
|
126
|
+
override fun onNewResultImpl(dataSource: DataSource<CloseableReference<PooledByteBuffer>>) {
|
|
127
|
+
if (!dataSource.isFinished) {
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
val ref = dataSource.result
|
|
131
|
+
if (ref != null) {
|
|
132
|
+
var encodedImage: EncodedImage? = null
|
|
133
|
+
try {
|
|
134
|
+
encodedImage = EncodedImage(ref)
|
|
135
|
+
// Swap width and height when the image's EXIF orientation swaps the X/Y axes
|
|
136
|
+
// (90°/270° rotations, or transpose/transverse), so the values reflect the
|
|
137
|
+
// visible dimensions, matching iOS behavior.
|
|
138
|
+
val rotated =
|
|
139
|
+
encodedImage.rotationAngle == 90 ||
|
|
140
|
+
encodedImage.rotationAngle == 270 ||
|
|
141
|
+
encodedImage.exifOrientation == ExifInterface.ORIENTATION_TRANSPOSE ||
|
|
142
|
+
encodedImage.exifOrientation == ExifInterface.ORIENTATION_TRANSVERSE
|
|
143
|
+
val width = if (rotated) encodedImage.height else encodedImage.width
|
|
144
|
+
val height = if (rotated) encodedImage.width else encodedImage.height
|
|
145
|
+
if (width < 0 || height < 0) {
|
|
146
|
+
promise.reject(ERROR_GET_SIZE_FAILURE, "Failed to get the size of the image")
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
val sizes = buildReadableMap {
|
|
150
|
+
put("width", width)
|
|
151
|
+
put("height", height)
|
|
160
152
|
}
|
|
161
|
-
|
|
162
|
-
|
|
153
|
+
promise.resolve(sizes)
|
|
154
|
+
} catch (e: Exception) {
|
|
155
|
+
promise.reject(ERROR_GET_SIZE_FAILURE, e)
|
|
156
|
+
} finally {
|
|
157
|
+
encodedImage?.close()
|
|
158
|
+
CloseableReference.closeSafely(ref)
|
|
163
159
|
}
|
|
160
|
+
} else {
|
|
161
|
+
promise.reject(ERROR_GET_SIZE_FAILURE, "Failed to get the size of the image")
|
|
164
162
|
}
|
|
163
|
+
}
|
|
165
164
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
165
|
+
override fun onFailureImpl(dataSource: DataSource<CloseableReference<PooledByteBuffer>>) {
|
|
166
|
+
promise.reject(ERROR_GET_SIZE_FAILURE, dataSource.failureCause)
|
|
169
167
|
}
|
|
170
|
-
|
|
171
|
-
}
|
|
168
|
+
}
|
|
172
169
|
|
|
173
170
|
/**
|
|
174
171
|
* Prefetches the given image to the Fresco image disk cache.
|
|
@@ -15,10 +15,16 @@ import android.graphics.drawable.ColorDrawable
|
|
|
15
15
|
import android.graphics.drawable.Drawable
|
|
16
16
|
import android.graphics.drawable.RippleDrawable
|
|
17
17
|
import android.util.TypedValue
|
|
18
|
+
import com.facebook.common.logging.FLog
|
|
19
|
+
import com.facebook.react.bridge.ColorPropConverter
|
|
20
|
+
import com.facebook.react.bridge.JSApplicationCausedNativeException
|
|
18
21
|
import com.facebook.react.bridge.JSApplicationIllegalArgumentException
|
|
19
22
|
import com.facebook.react.bridge.ReadableMap
|
|
23
|
+
import com.facebook.react.bridge.ReadableType
|
|
24
|
+
import com.facebook.react.common.ReactConstants
|
|
20
25
|
import com.facebook.react.uimanager.PixelUtil
|
|
21
26
|
import com.facebook.react.uimanager.ViewProps
|
|
27
|
+
import kotlin.math.roundToInt
|
|
22
28
|
|
|
23
29
|
/**
|
|
24
30
|
* Utility class that helps with converting android drawable description used in JS to an actual
|
|
@@ -73,11 +79,21 @@ public object ReactDrawableHelper {
|
|
|
73
79
|
context: Context,
|
|
74
80
|
drawableDescriptionDict: ReadableMap,
|
|
75
81
|
): RippleDrawable {
|
|
76
|
-
val
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
val resolvedColor = getColor(context, drawableDescriptionDict)
|
|
83
|
+
var color = resolvedColor ?: getFallbackColor(context)
|
|
84
|
+
|
|
85
|
+
if (
|
|
86
|
+
resolvedColor != null &&
|
|
87
|
+
drawableDescriptionDict.hasKey("alpha") &&
|
|
88
|
+
!drawableDescriptionDict.isNull("alpha")
|
|
89
|
+
) {
|
|
90
|
+
val alphaFactor = drawableDescriptionDict.getDouble("alpha").coerceIn(0.0, 1.0)
|
|
91
|
+
val newAlpha = (Color.alpha(color) * alphaFactor).roundToInt()
|
|
92
|
+
color = Color.argb(newAlpha, Color.red(color), Color.green(color), Color.blue(color))
|
|
93
|
+
}
|
|
79
94
|
|
|
80
|
-
|
|
95
|
+
val mask = getMask(drawableDescriptionDict)
|
|
96
|
+
return RippleDrawable(ColorStateList(arrayOf(intArrayOf()), intArrayOf(color)), null, mask)
|
|
81
97
|
}
|
|
82
98
|
|
|
83
99
|
private fun setRadius(drawableDescriptionDict: ReadableMap, drawable: Drawable?): Drawable? {
|
|
@@ -88,26 +104,49 @@ public object ReactDrawableHelper {
|
|
|
88
104
|
return drawable
|
|
89
105
|
}
|
|
90
106
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
} else {
|
|
107
|
+
/**
|
|
108
|
+
* Returns the resolved ripple color, or null if none was provided or the PlatformColor resource
|
|
109
|
+
* couldn't be found.
|
|
110
|
+
*/
|
|
111
|
+
private fun getColor(context: Context, drawableDescriptionDict: ReadableMap): Int? {
|
|
112
|
+
val rawColor: Any? =
|
|
98
113
|
if (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
resolveOutValue,
|
|
102
|
-
true,
|
|
103
|
-
)
|
|
114
|
+
drawableDescriptionDict.hasKey(ViewProps.COLOR) &&
|
|
115
|
+
!drawableDescriptionDict.isNull(ViewProps.COLOR)
|
|
104
116
|
) {
|
|
105
|
-
|
|
117
|
+
when (drawableDescriptionDict.getType(ViewProps.COLOR)) {
|
|
118
|
+
ReadableType.Number -> drawableDescriptionDict.getDouble(ViewProps.COLOR)
|
|
119
|
+
ReadableType.Map -> drawableDescriptionDict.getMap(ViewProps.COLOR)
|
|
120
|
+
else -> null
|
|
121
|
+
}
|
|
106
122
|
} else {
|
|
107
|
-
|
|
108
|
-
"Attribute colorControlHighlight couldn't be resolved into a drawable"
|
|
109
|
-
)
|
|
123
|
+
null
|
|
110
124
|
}
|
|
125
|
+
return try {
|
|
126
|
+
ColorPropConverter.getColor(rawColor, context)
|
|
127
|
+
} catch (e: JSApplicationCausedNativeException) {
|
|
128
|
+
FLog.w(
|
|
129
|
+
ReactConstants.TAG,
|
|
130
|
+
e,
|
|
131
|
+
"android_ripple: color resource not found, using colorControlHighlight",
|
|
132
|
+
)
|
|
133
|
+
null
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private fun getFallbackColor(context: Context): Int =
|
|
138
|
+
if (
|
|
139
|
+
context.theme.resolveAttribute(
|
|
140
|
+
android.R.attr.colorControlHighlight,
|
|
141
|
+
resolveOutValue,
|
|
142
|
+
true,
|
|
143
|
+
)
|
|
144
|
+
) {
|
|
145
|
+
context.resources.getColor(resolveOutValue.resourceId, context.theme)
|
|
146
|
+
} else {
|
|
147
|
+
throw JSApplicationIllegalArgumentException(
|
|
148
|
+
"Attribute colorControlHighlight couldn't be resolved into a drawable"
|
|
149
|
+
)
|
|
111
150
|
}
|
|
112
151
|
|
|
113
152
|
private fun getMask(drawableDescriptionDict: ReadableMap): Drawable? {
|
|
@@ -12,6 +12,7 @@ package com.facebook.react.views.view
|
|
|
12
12
|
import android.annotation.SuppressLint
|
|
13
13
|
import android.annotation.TargetApi
|
|
14
14
|
import android.content.Context
|
|
15
|
+
import android.content.res.Configuration
|
|
15
16
|
import android.graphics.BlendMode
|
|
16
17
|
import android.graphics.Canvas
|
|
17
18
|
import android.graphics.Paint
|
|
@@ -28,6 +29,7 @@ import com.facebook.react.R
|
|
|
28
29
|
import com.facebook.react.bridge.ReactNoCrashSoftException
|
|
29
30
|
import com.facebook.react.bridge.ReactSoftExceptionLogger
|
|
30
31
|
import com.facebook.react.bridge.ReactSoftExceptionLogger.logSoftException
|
|
32
|
+
import com.facebook.react.bridge.ReadableMap
|
|
31
33
|
import com.facebook.react.bridge.UiThreadUtil.assertOnUiThread
|
|
32
34
|
import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
|
|
33
35
|
import com.facebook.react.common.ReactConstants.TAG
|
|
@@ -154,6 +156,9 @@ public open class ReactViewGroup public constructor(context: Context?) :
|
|
|
154
156
|
null
|
|
155
157
|
private var focusOnAttach = false
|
|
156
158
|
|
|
159
|
+
internal var nativeBackgroundMap: ReadableMap? = null
|
|
160
|
+
internal var nativeForegroundMap: ReadableMap? = null
|
|
161
|
+
|
|
157
162
|
init {
|
|
158
163
|
initView()
|
|
159
164
|
}
|
|
@@ -181,6 +186,8 @@ public open class ReactViewGroup public constructor(context: Context?) :
|
|
|
181
186
|
backfaceOpacity = 1f
|
|
182
187
|
backfaceVisible = true
|
|
183
188
|
childrenRemovedWhileTransitioning = null
|
|
189
|
+
nativeBackgroundMap = null
|
|
190
|
+
nativeForegroundMap = null
|
|
184
191
|
}
|
|
185
192
|
|
|
186
193
|
internal open fun recycleView() {
|
|
@@ -587,6 +594,29 @@ public open class ReactViewGroup public constructor(context: Context?) :
|
|
|
587
594
|
}
|
|
588
595
|
}
|
|
589
596
|
|
|
597
|
+
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
598
|
+
super.onConfigurationChanged(newConfig)
|
|
599
|
+
if (nativeBackgroundMap != null) {
|
|
600
|
+
applyNativeBackground(nativeBackgroundMap)
|
|
601
|
+
}
|
|
602
|
+
if (nativeForegroundMap != null) {
|
|
603
|
+
applyNativeForeground(nativeForegroundMap)
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
internal fun applyNativeBackground(map: ReadableMap?) {
|
|
608
|
+
nativeBackgroundMap = map
|
|
609
|
+
setFeedbackUnderlay(
|
|
610
|
+
this,
|
|
611
|
+
map?.let { ReactDrawableHelper.createDrawableFromJSDescription(context, it) },
|
|
612
|
+
)
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
internal fun applyNativeForeground(map: ReadableMap?) {
|
|
616
|
+
nativeForegroundMap = map
|
|
617
|
+
foreground = map?.let { ReactDrawableHelper.createDrawableFromJSDescription(context, it) }
|
|
618
|
+
}
|
|
619
|
+
|
|
590
620
|
override fun onViewAdded(child: View) {
|
|
591
621
|
assertOnUiThread()
|
|
592
622
|
checkViewClippingTag(child, false)
|
|
@@ -305,17 +305,12 @@ public open class ReactViewManager : ReactClippingViewManager<ReactViewGroup>()
|
|
|
305
305
|
|
|
306
306
|
@ReactProp(name = "nativeBackgroundAndroid")
|
|
307
307
|
public open fun setNativeBackground(view: ReactViewGroup, background: ReadableMap?) {
|
|
308
|
-
|
|
309
|
-
ReactDrawableHelper.createDrawableFromJSDescription(view.context, it)
|
|
310
|
-
}
|
|
311
|
-
BackgroundStyleApplicator.setFeedbackUnderlay(view, bg)
|
|
308
|
+
view.applyNativeBackground(background)
|
|
312
309
|
}
|
|
313
310
|
|
|
314
311
|
@ReactProp(name = "nativeForegroundAndroid")
|
|
315
312
|
public open fun setNativeForeground(view: ReactViewGroup, foreground: ReadableMap?) {
|
|
316
|
-
view.foreground
|
|
317
|
-
ReactDrawableHelper.createDrawableFromJSDescription(view.context, it)
|
|
318
|
-
}
|
|
313
|
+
view.applyNativeForeground(foreground)
|
|
319
314
|
}
|
|
320
315
|
|
|
321
316
|
@ReactProp(name = ViewProps.NEEDS_OFFSCREEN_ALPHA_COMPOSITING)
|
|
@@ -450,8 +450,25 @@ inline static void updateNativeDrawableProp(
|
|
|
450
450
|
nativeDrawableResult["rippleRadius"] =
|
|
451
451
|
nativeDrawableValue.ripple.rippleRadius.value();
|
|
452
452
|
}
|
|
453
|
-
if (nativeDrawableValue.ripple.color.has_value()
|
|
454
|
-
|
|
453
|
+
if (nativeDrawableValue.ripple.color.has_value() ||
|
|
454
|
+
nativeDrawableValue.ripple.colorResourcePaths.has_value()) {
|
|
455
|
+
if (nativeDrawableValue.ripple.colorResourcePaths.has_value()) {
|
|
456
|
+
folly::dynamic resourcePaths = folly::dynamic::array();
|
|
457
|
+
for (const auto& path :
|
|
458
|
+
nativeDrawableValue.ripple.colorResourcePaths.value()) {
|
|
459
|
+
resourcePaths.push_back(path);
|
|
460
|
+
}
|
|
461
|
+
folly::dynamic platformColorMap = folly::dynamic::object();
|
|
462
|
+
platformColorMap["resource_paths"] = resourcePaths;
|
|
463
|
+
nativeDrawableResult["color"] = platformColorMap;
|
|
464
|
+
} else {
|
|
465
|
+
nativeDrawableResult["color"] =
|
|
466
|
+
toAndroidRepr(nativeDrawableValue.ripple.color.value());
|
|
467
|
+
}
|
|
468
|
+
if (nativeDrawableValue.ripple.alpha.has_value()) {
|
|
469
|
+
nativeDrawableResult["alpha"] =
|
|
470
|
+
nativeDrawableValue.ripple.alpha.value();
|
|
471
|
+
}
|
|
455
472
|
}
|
|
456
473
|
nativeDrawableResult["borderless"] = nativeDrawableValue.ripple.borderless;
|
|
457
474
|
} else {
|