react-native 0.84.0-nightly-20251211-80e384a80 → 0.84.0-nightly-20251213-07bd24ed0

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.
Files changed (23) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +97 -2
  3. package/Libraries/WebSocket/WebSocketInterceptor.js +3 -3
  4. package/React/Base/RCTVersion.m +1 -1
  5. package/React/Modules/RCTEventEmitter.m +1 -0
  6. package/ReactAndroid/gradle.properties +1 -1
  7. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/ChangeBundleLocationDialog.kt +11 -10
  8. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  9. package/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/PackagerConnectionSettings.kt +15 -8
  10. package/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp +34 -8
  11. package/ReactAndroid/src/main/res/views/uimanager/values-ne/strings.xml +1 -0
  12. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  13. package/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.h +16 -0
  14. package/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp +16 -10
  15. package/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h +2 -0
  16. package/jest/mockComponent.js +1 -1
  17. package/package.json +9 -9
  18. package/sdks/hermes-engine/version.properties +1 -1
  19. package/src/private/devsupport/devmenu/elementinspector/Inspector.js +6 -25
  20. package/src/private/devsupport/devmenu/elementinspector/InspectorPanel.js +0 -26
  21. package/src/private/devsupport/devmenu/elementinspector/XHRInterceptor.js +3 -2
  22. package/src/private/devsupport/devmenu/elementinspector/NetworkOverlay.js +0 -628
  23. package/src/private/devsupport/devmenu/perfmonitor/PerformanceOverlay.js +0 -66
@@ -29,7 +29,7 @@ export default class ReactNativeVersion {
29
29
  static major: number = 0;
30
30
  static minor: number = 84;
31
31
  static patch: number = 0;
32
- static prerelease: string | null = 'nightly-20251211-80e384a80';
32
+ static prerelease: string | null = 'nightly-20251213-07bd24ed0';
33
33
 
34
34
  static getVersionString(): string {
35
35
  return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
@@ -367,7 +367,7 @@ export type BlendMode =
367
367
  | 'color'
368
368
  | 'luminosity';
369
369
 
370
- export type GradientValue = {
370
+ export type LinearGradientValue = {
371
371
  type: 'linear-gradient';
372
372
  // Angle or direction enums
373
373
  direction?: string | undefined;
@@ -377,6 +377,89 @@ export type GradientValue = {
377
377
  }>;
378
378
  };
379
379
 
380
+ export type GradientValue = LinearGradientValue;
381
+
382
+ type RadialExtent =
383
+ | 'closest-corner'
384
+ | 'closest-side'
385
+ | 'farthest-corner'
386
+ | 'farthest-side';
387
+ export type RadialGradientPosition =
388
+ | {
389
+ top: number | string;
390
+ left: number | string;
391
+ }
392
+ | {
393
+ top: number | string;
394
+ right: number | string;
395
+ }
396
+ | {
397
+ bottom: number | string;
398
+ left: number | string;
399
+ }
400
+ | {
401
+ bottom: number | string;
402
+ right: number | string;
403
+ };
404
+
405
+ export type RadialGradientShape = 'circle' | 'ellipse';
406
+ export type RadialGradientSize =
407
+ | RadialExtent
408
+ | {
409
+ x: string | number;
410
+ y: string | number;
411
+ };
412
+
413
+ type RadialGradientValue = {
414
+ type: 'radial-gradient';
415
+ shape: RadialGradientShape;
416
+ size: RadialGradientSize;
417
+ position: RadialGradientPosition;
418
+ colorStops: ReadonlyArray<{
419
+ color: ColorValue | null;
420
+ positions?: ReadonlyArray<string> | undefined;
421
+ }>;
422
+ };
423
+
424
+ export type BackgroundImageValue = LinearGradientValue | RadialGradientValue;
425
+
426
+ export type BackgroundSizeValue =
427
+ | {
428
+ x: string | number;
429
+ y: string | number;
430
+ }
431
+ | 'cover'
432
+ | 'contain';
433
+
434
+ export type BackgroundRepeatKeyword =
435
+ | 'repeat'
436
+ | 'space'
437
+ | 'round'
438
+ | 'no-repeat';
439
+
440
+ export type BackgroundPositionValue =
441
+ | {
442
+ top: number | string;
443
+ left: number | string;
444
+ }
445
+ | {
446
+ top: number | string;
447
+ right: number | string;
448
+ }
449
+ | {
450
+ bottom: number | string;
451
+ left: number | string;
452
+ }
453
+ | {
454
+ bottom: number | string;
455
+ right: number | string;
456
+ };
457
+
458
+ export type BackgroundRepeatValue = {
459
+ x: BackgroundRepeatKeyword;
460
+ y: BackgroundRepeatKeyword;
461
+ };
462
+
380
463
  /**
381
464
  * @see https://reactnative.dev/docs/view#style
382
465
  */
@@ -437,7 +520,19 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
437
520
 
438
521
  mixBlendMode?: BlendMode | undefined;
439
522
  experimental_backgroundImage?:
440
- | ReadonlyArray<GradientValue>
523
+ | ReadonlyArray<BackgroundImageValue>
524
+ | string
525
+ | undefined;
526
+ experimental_backgroundSize?:
527
+ | ReadonlyArray<BackgroundSizeValue>
528
+ | string
529
+ | undefined;
530
+ experimental_backgroundPosition?:
531
+ | ReadonlyArray<BackgroundPositionValue>
532
+ | string
533
+ | undefined;
534
+ experimental_backgroundRepeat?:
535
+ | ReadonlyArray<BackgroundRepeatValue>
441
536
  | string
442
537
  | undefined;
443
538
  }
@@ -33,10 +33,10 @@ let isInterceptorEnabled = false;
33
33
 
34
34
  /**
35
35
  * A network interceptor which monkey-patches RCTWebSocketModule methods
36
- * to gather all websocket network requests/responses, in order to show
37
- * their information in the React Native inspector development tool.
36
+ * to gather all websocket network events.
37
+ *
38
+ * @deprecated Since React Native 0.84
38
39
  */
39
-
40
40
  const WebSocketInterceptor = {
41
41
  /**
42
42
  * Invoked when RCTWebSocketModule.close(...) is called.
@@ -24,7 +24,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(84),
26
26
  RCTVersionPatch: @(0),
27
- RCTVersionPrerelease: @"nightly-20251211-80e384a80",
27
+ RCTVersionPrerelease: @"nightly-20251213-07bd24ed0",
28
28
  };
29
29
  });
30
30
  return __rnVersion;
@@ -89,6 +89,7 @@
89
89
 
90
90
  if (_listenerCount > 0) {
91
91
  [self stopObserving];
92
+ _listenerCount = 0;
92
93
  }
93
94
  }
94
95
 
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.84.0-nightly-20251211-80e384a80
1
+ VERSION_NAME=0.84.0-nightly-20251213-07bd24ed0
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
  react.internal.hermesPublishingGroup=com.facebook.hermes
4
4
 
@@ -33,9 +33,6 @@ internal object ChangeBundleLocationDialog {
33
33
  ) {
34
34
  val settings = devSettings.packagerConnectionSettings
35
35
  val currentHost = settings.debugServerHost
36
- settings.debugServerHost = ""
37
- val defaultHost = settings.debugServerHost
38
- settings.debugServerHost = currentHost
39
36
 
40
37
  val layout = LinearLayout(context)
41
38
  layout.orientation = LinearLayout.VERTICAL
@@ -60,11 +57,11 @@ internal object ChangeBundleLocationDialog {
60
57
  input.setTextColor(-0x1000000)
61
58
  input.setText(currentHost)
62
59
 
63
- val defaultHostSuggestion = Button(context)
64
- defaultHostSuggestion.text = defaultHost
65
- defaultHostSuggestion.textSize = 12f
66
- defaultHostSuggestion.isAllCaps = false
67
- defaultHostSuggestion.setOnClickListener { input.setText(defaultHost) }
60
+ val currentHostSuggestion = Button(context)
61
+ currentHostSuggestion.text = currentHost
62
+ currentHostSuggestion.textSize = 12f
63
+ currentHostSuggestion.isAllCaps = false
64
+ currentHostSuggestion.setOnClickListener { input.setText(currentHost) }
68
65
 
69
66
  val networkHost = getDevServerNetworkIpAndPort(context)
70
67
  val networkHostSuggestion = Button(context)
@@ -80,8 +77,12 @@ internal object ChangeBundleLocationDialog {
80
77
  LinearLayout.LayoutParams.MATCH_PARENT,
81
78
  LinearLayout.LayoutParams.WRAP_CONTENT,
82
79
  )
83
- suggestionRow.addView(defaultHostSuggestion)
84
- suggestionRow.addView(networkHostSuggestion)
80
+ suggestionRow.addView(currentHostSuggestion)
81
+
82
+ if (currentHost != networkHost) {
83
+ // We don't want to display two buttons with the same host suggestion.
84
+ suggestionRow.addView(networkHostSuggestion)
85
+ }
85
86
 
86
87
  val instructions = TextView(context)
87
88
  instructions.text =
@@ -15,6 +15,6 @@ public object ReactNativeVersion {
15
15
  "major" to 0,
16
16
  "minor" to 84,
17
17
  "patch" to 0,
18
- "prerelease" to "nightly-20251211-80e384a80"
18
+ "prerelease" to "nightly-20251213-07bd24ed0"
19
19
  )
20
20
  }
@@ -19,15 +19,16 @@ public open class PackagerConnectionSettings(private val appContext: Context) {
19
19
  private val preferences: SharedPreferences =
20
20
  PreferenceManager.getDefaultSharedPreferences(appContext)
21
21
  public val packageName: String = appContext.packageName
22
- private val _additionalOptionsForPackager: MutableMap<String, String> = mutableMapOf()
23
- private var _packagerOptionsUpdater: (Map<String, String>) -> Map<String, String> = { it }
24
- private var cachedHost: String? = null
22
+
23
+ init {
24
+ resetDebugServerHost()
25
+ }
25
26
 
26
27
  public open var debugServerHost: String
27
28
  get() {
28
29
  // Check cached host first. If empty try to detect emulator type and use default
29
30
  // hostname for those
30
- cachedHost?.let {
31
+ _cachedOrOverrideHost?.let {
31
32
  return it
32
33
  }
33
34
 
@@ -44,19 +45,19 @@ public open class PackagerConnectionSettings(private val appContext: Context) {
44
45
  )
45
46
  }
46
47
 
47
- cachedHost = host
48
+ _cachedOrOverrideHost = host
48
49
  return host
49
50
  }
50
51
  set(host) {
51
52
  if (host.isEmpty()) {
52
- cachedHost = null
53
+ _cachedOrOverrideHost = null
53
54
  } else {
54
- cachedHost = host
55
+ _cachedOrOverrideHost = host
55
56
  }
56
57
  }
57
58
 
58
59
  public open fun resetDebugServerHost() {
59
- cachedHost = null
60
+ _cachedOrOverrideHost = null
60
61
  }
61
62
 
62
63
  public fun setPackagerOptionsUpdater(queryMapper: (Map<String, String>) -> Map<String, String>) {
@@ -76,5 +77,11 @@ public open class PackagerConnectionSettings(private val appContext: Context) {
76
77
  private companion object {
77
78
  private val TAG = PackagerConnectionSettings::class.java.simpleName
78
79
  private const val PREFS_DEBUG_SERVER_HOST_KEY = "debug_http_host"
80
+
81
+ // The state for this class needs to be retained in the companion object.
82
+ // That's necessary in the case when there are multiple instances of PackagerConnectionSettings
83
+ private var _cachedOrOverrideHost: String? = null
84
+ private val _additionalOptionsForPackager: MutableMap<String, String> = mutableMapOf()
85
+ private var _packagerOptionsUpdater: (Map<String, String>) -> Map<String, String> = { it }
79
86
  }
80
87
  }
@@ -176,11 +176,24 @@ std::shared_ptr<TurboModule> TurboModuleManager::getTurboModule(
176
176
  return turboModule;
177
177
  }
178
178
 
179
+ // TODO(T248203434): Remove this workaround once fixed in fbjni
180
+ // NOTE: We use jstring instead of std::string for the method signature to
181
+ // work around a bug in fbjni's exception handling. When a Java method throws
182
+ // an exception, fbjni's JMethod::operator() needs to check for pending
183
+ // exceptions via FACEBOOK_JNI_THROW_PENDING_EXCEPTION(). However, if we pass
184
+ // std::string, fbjni creates a temporary local_ref<JString> for the argument.
185
+ // C++ destroys temporaries at the end of the full-expression, which happens
186
+ // AFTER the JNI call returns but BEFORE the exception check. The destructor
187
+ // calls JNI functions (GetObjectRefType) while there's a pending exception,
188
+ // which violates JNI rules and causes ART's CheckJNI to abort the process.
189
+ //
190
+ // By pre-converting to jstring here, we control the lifetime of the
191
+ // local_ref<JString> so it extends past the exception check.
179
192
  static auto getTurboJavaModule =
180
- javaPart->getClass()
181
- ->getMethod<jni::alias_ref<JTurboModule>(const std::string&)>(
182
- "getTurboJavaModule");
183
- auto moduleInstance = getTurboJavaModule(javaPart.get(), name);
193
+ javaPart->getClass()->getMethod<jni::alias_ref<JTurboModule>(jstring)>(
194
+ "getTurboJavaModule");
195
+ auto jname = jni::make_jstring(name);
196
+ auto moduleInstance = getTurboJavaModule(javaPart.get(), jname.get());
184
197
  if (moduleInstance) {
185
198
  TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName);
186
199
  JavaTurboModule::InitParams params = {
@@ -243,11 +256,24 @@ std::shared_ptr<TurboModule> TurboModuleManager::getLegacyModule(
243
256
 
244
257
  TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName);
245
258
 
259
+ // TODO(T248203434): Remove this workaround once fixed in fbjni
260
+ // NOTE: We use jstring instead of std::string for the method signature to
261
+ // work around a bug in fbjni's exception handling. When a Java method throws
262
+ // an exception, fbjni's JMethod::operator() needs to check for pending
263
+ // exceptions via FACEBOOK_JNI_THROW_PENDING_EXCEPTION(). However, if we pass
264
+ // std::string, fbjni creates a temporary local_ref<JString> for the argument.
265
+ // C++ destroys temporaries at the end of the full-expression, which happens
266
+ // AFTER the JNI call returns but BEFORE the exception check. The destructor
267
+ // calls JNI functions (GetObjectRefType) while there's a pending exception,
268
+ // which violates JNI rules and causes ART's CheckJNI to abort the process.
269
+ //
270
+ // By pre-converting to jstring here, we control the lifetime of the
271
+ // local_ref<JString> so it extends past the exception check.
246
272
  static auto getLegacyJavaModule =
247
- javaPart->getClass()
248
- ->getMethod<jni::alias_ref<JNativeModule>(const std::string&)>(
249
- "getLegacyJavaModule");
250
- auto moduleInstance = getLegacyJavaModule(javaPart.get(), name);
273
+ javaPart->getClass()->getMethod<jni::alias_ref<JNativeModule>(jstring)>(
274
+ "getLegacyJavaModule");
275
+ auto jname = jni::make_jstring(name);
276
+ auto moduleInstance = getLegacyJavaModule(javaPart.get(), jname.get());
251
277
 
252
278
  if (moduleInstance) {
253
279
  TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName);
@@ -12,6 +12,7 @@
12
12
  <string name="menubar_description" gender="unknown">मेनु बार</string>
13
13
  <string name="menuitem_description" gender="unknown">मेनु वस्तु</string>
14
14
  <string name="scrollbar_description" gender="unknown">स्क्रोल बार</string>
15
+ <string name="spinbutton_description" gender="unknown">स्पिन बटन</string>
15
16
  <string name="rn_tab_description" gender="unknown">टयाब</string>
16
17
  <string name="timer_description" gender="unknown">टाइमर</string>
17
18
  <string name="state_busy_description" gender="unknown">व्यस्त</string>
@@ -22,7 +22,7 @@ constexpr struct {
22
22
  int32_t Major = 0;
23
23
  int32_t Minor = 84;
24
24
  int32_t Patch = 0;
25
- std::string_view Prerelease = "nightly-20251211-80e384a80";
25
+ std::string_view Prerelease = "nightly-20251213-07bd24ed0";
26
26
  } ReactNativeVersion;
27
27
 
28
28
  } // namespace facebook::react
@@ -77,6 +77,22 @@ inline void updateProp(const PropName propName, BaseViewProps &viewProps, const
77
77
  case BACKGROUND_COLOR:
78
78
  viewProps.backgroundColor = snapshot.props.backgroundColor;
79
79
  break;
80
+
81
+ case SHADOW_COLOR:
82
+ viewProps.shadowColor = snapshot.props.shadowColor;
83
+ break;
84
+
85
+ case SHADOW_OFFSET:
86
+ viewProps.shadowOffset = snapshot.props.shadowOffset;
87
+ break;
88
+
89
+ case SHADOW_OPACITY:
90
+ viewProps.shadowOpacity = snapshot.props.shadowOpacity;
91
+ break;
92
+
93
+ case SHADOW_RADIUS:
94
+ viewProps.shadowRadius = snapshot.props.shadowRadius;
95
+ break;
80
96
  }
81
97
  }
82
98
 
@@ -24,11 +24,14 @@ ImageRequest ImageFetcher::requestImage(
24
24
  SurfaceId surfaceId,
25
25
  const ImageRequestParams& imageRequestParams,
26
26
  Tag tag) {
27
- items_[surfaceId].emplace_back(
28
- ImageRequestItem{
29
- .imageSource = imageSource,
30
- .imageRequestParams = imageRequestParams,
31
- .tag = tag});
27
+ {
28
+ std::lock_guard<std::mutex> lock(mutex_);
29
+ items_[surfaceId].emplace_back(
30
+ ImageRequestItem{
31
+ .imageSource = imageSource,
32
+ .imageRequestParams = imageRequestParams,
33
+ .tag = tag});
34
+ }
32
35
 
33
36
  auto telemetry = std::make_shared<ImageTelemetry>(surfaceId);
34
37
 
@@ -40,8 +43,13 @@ ImageRequest ImageFetcher::requestImage(
40
43
  }
41
44
 
42
45
  void ImageFetcher::flushImageRequests() {
43
- if (items_.empty()) {
44
- return;
46
+ std::unordered_map<SurfaceId, std::vector<ImageRequestItem>> items;
47
+ {
48
+ std::lock_guard<std::mutex> lock(mutex_);
49
+ if (items_.empty()) {
50
+ return;
51
+ }
52
+ items.swap(items_);
45
53
  }
46
54
 
47
55
  auto fabricUIManager_ =
@@ -52,14 +60,12 @@ void ImageFetcher::flushImageRequests() {
52
60
  SurfaceId, std::string, JReadableMapBuffer::javaobject)>(
53
61
  "experimental_prefetchResources");
54
62
 
55
- for (auto& [surfaceId, surfaceImageRequests] : items_) {
63
+ for (auto& [surfaceId, surfaceImageRequests] : items) {
56
64
  auto readableMapBuffer = JReadableMapBuffer::createWithContents(
57
65
  serializeImageRequests(surfaceImageRequests));
58
66
  prefetchResources(
59
67
  fabricUIManager_, surfaceId, "RCTImageView", readableMapBuffer.get());
60
68
  }
61
-
62
- items_.clear();
63
69
  }
64
70
 
65
71
  } // namespace facebook::react
@@ -11,6 +11,7 @@
11
11
  #include <react/renderer/imagemanager/ImageRequestParams.h>
12
12
  #include <react/utils/ContextContainer.h>
13
13
  #include <memory>
14
+ #include <mutex>
14
15
  #include <unordered_map>
15
16
  #include <vector>
16
17
 
@@ -38,6 +39,7 @@ class ImageFetcher {
38
39
  Tag tag);
39
40
 
40
41
  std::unordered_map<SurfaceId, std::vector<ImageRequestItem>> items_;
42
+ std::mutex mutex_;
41
43
  std::shared_ptr<const ContextContainer> contextContainer_;
42
44
  };
43
45
  } // namespace facebook::react
@@ -39,7 +39,7 @@ export default function mockComponent<
39
39
 
40
40
  const SuperClass: typeof React.Component<{...}> =
41
41
  typeof RealComponent === 'function' &&
42
- RealComponent.prototype.constructor instanceof React.Component
42
+ RealComponent.prototype?.constructor instanceof React.Component
43
43
  ? RealComponent
44
44
  : React.Component;
45
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native",
3
- "version": "0.84.0-nightly-20251211-80e384a80",
3
+ "version": "0.84.0-nightly-20251213-07bd24ed0",
4
4
  "description": "A framework for building native apps using React",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -160,13 +160,13 @@
160
160
  },
161
161
  "dependencies": {
162
162
  "@jest/create-cache-key-function": "^29.7.0",
163
- "@react-native/assets-registry": "0.84.0-nightly-20251211-80e384a80",
164
- "@react-native/codegen": "0.84.0-nightly-20251211-80e384a80",
165
- "@react-native/community-cli-plugin": "0.84.0-nightly-20251211-80e384a80",
166
- "@react-native/gradle-plugin": "0.84.0-nightly-20251211-80e384a80",
167
- "@react-native/js-polyfills": "0.84.0-nightly-20251211-80e384a80",
168
- "@react-native/normalize-colors": "0.84.0-nightly-20251211-80e384a80",
169
- "@react-native/virtualized-lists": "0.84.0-nightly-20251211-80e384a80",
163
+ "@react-native/assets-registry": "0.84.0-nightly-20251213-07bd24ed0",
164
+ "@react-native/codegen": "0.84.0-nightly-20251213-07bd24ed0",
165
+ "@react-native/community-cli-plugin": "0.84.0-nightly-20251213-07bd24ed0",
166
+ "@react-native/gradle-plugin": "0.84.0-nightly-20251213-07bd24ed0",
167
+ "@react-native/js-polyfills": "0.84.0-nightly-20251213-07bd24ed0",
168
+ "@react-native/normalize-colors": "0.84.0-nightly-20251213-07bd24ed0",
169
+ "@react-native/virtualized-lists": "0.84.0-nightly-20251213-07bd24ed0",
170
170
  "abort-controller": "^3.0.0",
171
171
  "anser": "^1.4.9",
172
172
  "ansi-regex": "^5.0.0",
@@ -175,7 +175,7 @@
175
175
  "base64-js": "^1.5.1",
176
176
  "commander": "^12.0.0",
177
177
  "flow-enums-runtime": "^0.0.6",
178
- "hermes-compiler": "0.14.0-commitly-202512102158-39fca9fda",
178
+ "hermes-compiler": "0.15.0-commitly-202512121350-fd0e1d3ed",
179
179
  "invariant": "^2.2.4",
180
180
  "jest-environment-node": "^29.7.0",
181
181
  "memoize-one": "^5.0.0",
@@ -1,2 +1,2 @@
1
- HERMES_VERSION_NAME=0.14.0-commitly-202512102158-39fca9fda
1
+ HERMES_VERSION_NAME=0.15.0-commitly-202512121350-fd0e1d3ed
2
2
  HERMES_V1_VERSION_NAME=250829098.0.4
@@ -39,10 +39,6 @@ const InspectorPanel = require('./InspectorPanel').default;
39
39
  const {useState} = React;
40
40
 
41
41
  type PanelPosition = 'top' | 'bottom';
42
- type SelectedTab =
43
- | 'elements-inspector'
44
- | 'network-profiling'
45
- | 'performance-profiling';
46
42
 
47
43
  export type InspectedElementFrame = TouchedViewDataAtPoint['frame'];
48
44
  export type InspectedElement = $ReadOnly<{
@@ -62,8 +58,7 @@ function Inspector({
62
58
  onRequestRerenderApp,
63
59
  reactDevToolsAgent,
64
60
  }: Props): React.Node {
65
- const [selectedTab, setSelectedTab] =
66
- useState<?SelectedTab>('elements-inspector');
61
+ const [inspecting, setInspecting] = useState<boolean>(true);
67
62
 
68
63
  const [panelPosition, setPanelPosition] = useState<PanelPosition>('bottom');
69
64
  const [inspectedElement, setInspectedElement] =
@@ -137,18 +132,8 @@ function Inspector({
137
132
  );
138
133
  };
139
134
 
140
- const setInspecting = (enabled: boolean) => {
141
- setSelectedTab(enabled ? 'elements-inspector' : null);
142
- setInspectedElement(null);
143
- };
144
-
145
- const setPerfing = (enabled: boolean) => {
146
- setSelectedTab(enabled ? 'performance-profiling' : null);
147
- setInspectedElement(null);
148
- };
149
-
150
- const setNetworking = (enabled: boolean) => {
151
- setSelectedTab(enabled ? 'network-profiling' : null);
135
+ const handleSetInspecting = (enabled: boolean) => {
136
+ setInspecting(enabled);
152
137
  setInspectedElement(null);
153
138
  };
154
139
 
@@ -164,7 +149,7 @@ function Inspector({
164
149
 
165
150
  return (
166
151
  <View style={styles.container} pointerEvents="box-none">
167
- {selectedTab === 'elements-inspector' && (
152
+ {inspecting && (
168
153
  <InspectorOverlay
169
154
  inspected={inspectedElement}
170
155
  onTouchPoint={onTouchPoint}
@@ -174,18 +159,14 @@ function Inspector({
174
159
  <SafeAreaView style={[styles.panelContainer, panelContainerStyle]}>
175
160
  <InspectorPanel
176
161
  devtoolsIsOpen={!!reactDevToolsAgent}
177
- inspecting={selectedTab === 'elements-inspector'}
178
- perfing={selectedTab === 'performance-profiling'}
179
- setPerfing={setPerfing}
180
- setInspecting={setInspecting}
162
+ inspecting={inspecting}
163
+ setInspecting={handleSetInspecting}
181
164
  inspected={inspectedElement}
182
165
  hierarchy={elementsHierarchy}
183
166
  selection={selectionIndex}
184
167
  setSelection={setSelection}
185
168
  touchTargeting={PressabilityDebug.isEnabled()}
186
169
  setTouchTargeting={setTouchTargeting}
187
- networking={selectedTab === 'network-profiling'}
188
- setNetworking={setNetworking}
189
170
  />
190
171
  </SafeAreaView>
191
172
  </View>
@@ -23,20 +23,14 @@ const View = require('../../../../../Libraries/Components/View/View').default;
23
23
  const StyleSheet =
24
24
  require('../../../../../Libraries/StyleSheet/StyleSheet').default;
25
25
  const Text = require('../../../../../Libraries/Text/Text').default;
26
- const PerformanceOverlay = require('../perfmonitor/PerformanceOverlay').default;
27
26
  const ElementProperties = require('./ElementProperties').default;
28
- const NetworkOverlay = require('./NetworkOverlay').default;
29
27
 
30
28
  type Props = $ReadOnly<{
31
29
  devtoolsIsOpen: boolean,
32
30
  inspecting: boolean,
33
31
  setInspecting: (val: boolean) => void,
34
- perfing: boolean,
35
- setPerfing: (val: boolean) => void,
36
32
  touchTargeting: boolean,
37
33
  setTouchTargeting: (val: boolean) => void,
38
- networking: boolean,
39
- setNetworking: (val: boolean) => void,
40
34
  hierarchy?: ?ElementsHierarchy,
41
35
  selection?: ?number,
42
36
  setSelection: number => mixed,
@@ -67,10 +61,6 @@ class InspectorPanel extends React.Component<Props> {
67
61
  />
68
62
  </ScrollView>
69
63
  );
70
- } else if (this.props.perfing) {
71
- contents = <PerformanceOverlay />;
72
- } else if (this.props.networking) {
73
- contents = <NetworkOverlay />;
74
64
  } else {
75
65
  contents = <View style={styles.waiting}>{this.renderWaiting()}</View>;
76
66
  }
@@ -83,22 +73,6 @@ class InspectorPanel extends React.Component<Props> {
83
73
  pressed={this.props.inspecting}
84
74
  onClick={this.props.setInspecting}
85
75
  />
86
- {global.RN$Bridgeless === true ? null : (
87
- // These Inspector Panel sub-features are removed under the New Arch.
88
- // See https://github.com/react-native-community/discussions-and-proposals/pull/777
89
- <>
90
- <InspectorPanelButton
91
- title={'Perf'}
92
- pressed={this.props.perfing}
93
- onClick={this.props.setPerfing}
94
- />
95
- <InspectorPanelButton
96
- title={'Network'}
97
- pressed={this.props.networking}
98
- onClick={this.props.setNetworking}
99
- />
100
- </>
101
- )}
102
76
  <InspectorPanelButton
103
77
  title={'Touchables'}
104
78
  pressed={this.props.touchTargeting}
@@ -64,10 +64,11 @@ let isInterceptorEnabled = false;
64
64
 
65
65
  /**
66
66
  * A network interceptor which monkey-patches XMLHttpRequest methods
67
- * to gather all network requests/responses, in order to show their
68
- * information in the React Native inspector development tool.
67
+ * to gather all network requests/responses.
69
68
  * This supports interception with XMLHttpRequest API, including Fetch API
70
69
  * and any other third party libraries that depend on XMLHttpRequest.
70
+ *
71
+ * @deprecated Since React Native 0.84
71
72
  */
72
73
  const XHRInterceptor = {
73
74
  /**
@@ -1,628 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- * @format
9
- */
10
-
11
- 'use strict';
12
-
13
- import type XMLHttpRequest from '../../../../../Libraries/Network/XMLHttpRequest';
14
- import type {ListRenderItemInfo} from '@react-native/virtualized-lists';
15
-
16
- import ScrollView from '../../../../../Libraries/Components/ScrollView/ScrollView';
17
- import * as React from 'react';
18
-
19
- const TouchableHighlight =
20
- require('../../../../../Libraries/Components/Touchable/TouchableHighlight').default;
21
- const View = require('../../../../../Libraries/Components/View/View').default;
22
- const FlatList = require('../../../../../Libraries/Lists/FlatList').default;
23
- const StyleSheet =
24
- require('../../../../../Libraries/StyleSheet/StyleSheet').default;
25
- const Text = require('../../../../../Libraries/Text/Text').default;
26
- const WebSocketInterceptor =
27
- require('../../../../../Libraries/WebSocket/WebSocketInterceptor').default;
28
- const XHRInterceptor = require('./XHRInterceptor').default;
29
-
30
- const LISTVIEW_CELL_HEIGHT = 15;
31
-
32
- // Global id for the intercepted XMLHttpRequest objects.
33
- let nextXHRId = 0;
34
-
35
- type NetworkRequestInfo = {
36
- id: number,
37
- type?: string,
38
- url?: string,
39
- method?: string,
40
- status?: number,
41
- dataSent?: any,
42
- responseContentType?: string,
43
- responseSize?: number,
44
- requestHeaders?: Object,
45
- responseHeaders?: string,
46
- response?: Object | string,
47
- responseURL?: string,
48
- responseType?: string,
49
- timeout?: number,
50
- closeReason?: string,
51
- messages?: string,
52
- serverClose?: Object,
53
- serverError?: Object,
54
- ...
55
- };
56
-
57
- type Props = $ReadOnly<{}>;
58
- type State = {
59
- detailRowId: ?number,
60
- requests: Array<NetworkRequestInfo>,
61
- };
62
-
63
- function getStringByValue(value: any): string {
64
- if (value === undefined) {
65
- return 'undefined';
66
- }
67
- if (typeof value === 'object') {
68
- return JSON.stringify(value);
69
- }
70
- if (typeof value === 'string' && value.length > 500) {
71
- return String(value)
72
- .slice(0, 500)
73
- .concat('\n***TRUNCATED TO 500 CHARACTERS***');
74
- }
75
- return value;
76
- }
77
-
78
- function getTypeShortName(type: any): string {
79
- if (type === 'XMLHttpRequest') {
80
- return 'XHR';
81
- } else if (type === 'WebSocket') {
82
- return 'WS';
83
- }
84
-
85
- return '';
86
- }
87
-
88
- function keyExtractor(request: NetworkRequestInfo): string {
89
- return String(request.id);
90
- }
91
-
92
- const XHR_ID_KEY = Symbol('XHR_ID');
93
-
94
- function getXHRId(xhr: XMLHttpRequest): number {
95
- // $FlowExpectedError[prop-missing]
96
- return xhr[XHR_ID_KEY];
97
- }
98
-
99
- function setXHRId(xhr: XMLHttpRequest, id: number) {
100
- // $FlowExpectedError[prop-missing]
101
- xhr[XHR_ID_KEY] = id;
102
- }
103
-
104
- /**
105
- * Show all the intercepted network requests over the InspectorPanel.
106
- */
107
- class NetworkOverlay extends React.Component<Props, State> {
108
- _requestsListView: ?React.ElementRef<Class<FlatList<NetworkRequestInfo>>>;
109
- _detailScrollView: ?React.ElementRef<typeof ScrollView>;
110
-
111
- // Metrics are used to decide when if the request list should be sticky, and
112
- // scroll to the bottom as new network requests come in, or if the user has
113
- // intentionally scrolled away from the bottom - to instead flash the scroll bar
114
- // and keep the current position
115
- _requestsListViewScrollMetrics: {
116
- contentLength: number,
117
- offset: number,
118
- visibleLength: number,
119
- } = {
120
- offset: 0,
121
- visibleLength: 0,
122
- contentLength: 0,
123
- };
124
-
125
- // Map of `socketId` -> `index in `this.state.requests`.
126
- _socketIdMap: {[number]: number} = {};
127
- // Map of `xhr[XHR_ID_KEY]` -> `index in `this.state.requests`.
128
- _xhrIdMap: {[key: number]: number, ...} = {};
129
-
130
- state: State = {
131
- detailRowId: null,
132
- requests: [],
133
- };
134
-
135
- _enableXHRInterception(): void {
136
- if (XHRInterceptor.isInterceptorEnabled()) {
137
- return;
138
- }
139
- // Show the XHR request item in listView as soon as it was opened.
140
- XHRInterceptor.setOpenCallback((method, url, xhr) => {
141
- // Generate a global id for each intercepted xhr object, add this id
142
- // to the xhr object as a private `_index` property to identify it,
143
- // so that we can distinguish different xhr objects in callbacks.
144
- setXHRId(xhr, nextXHRId++);
145
- const xhrIndex = this.state.requests.length;
146
- this._xhrIdMap[getXHRId(xhr)] = xhrIndex;
147
-
148
- const _xhr: NetworkRequestInfo = {
149
- id: xhrIndex,
150
- type: 'XMLHttpRequest',
151
- method: method,
152
- url: url,
153
- };
154
- this.setState(
155
- {
156
- requests: this.state.requests.concat(_xhr),
157
- },
158
- this._indicateAdditionalRequests,
159
- );
160
- });
161
-
162
- XHRInterceptor.setRequestHeaderCallback((header, value, xhr) => {
163
- // $FlowFixMe[prop-missing]
164
- const xhrIndex = this._getRequestIndexByXHRID(getXHRId(xhr));
165
- if (xhrIndex === -1) {
166
- return;
167
- }
168
-
169
- this.setState(({requests}) => {
170
- const networkRequestInfo = requests[xhrIndex];
171
- if (!networkRequestInfo.requestHeaders) {
172
- networkRequestInfo.requestHeaders = ({}: {[any]: any});
173
- }
174
- networkRequestInfo.requestHeaders[header] = value;
175
- return {requests};
176
- });
177
- });
178
-
179
- XHRInterceptor.setSendCallback((data, xhr) => {
180
- // $FlowFixMe[prop-missing]
181
- const xhrIndex = this._getRequestIndexByXHRID(getXHRId(xhr));
182
- if (xhrIndex === -1) {
183
- return;
184
- }
185
-
186
- this.setState(({requests}) => {
187
- const networkRequestInfo = requests[xhrIndex];
188
- networkRequestInfo.dataSent = data;
189
- return {requests};
190
- });
191
- });
192
-
193
- XHRInterceptor.setHeaderReceivedCallback(
194
- (type, size, responseHeaders, xhr) => {
195
- // $FlowFixMe[prop-missing]
196
- const xhrIndex = this._getRequestIndexByXHRID(getXHRId(xhr));
197
- if (xhrIndex === -1) {
198
- return;
199
- }
200
-
201
- this.setState(({requests}) => {
202
- const networkRequestInfo = requests[xhrIndex];
203
- networkRequestInfo.responseContentType = type;
204
- networkRequestInfo.responseSize = size;
205
- networkRequestInfo.responseHeaders = responseHeaders;
206
- return {requests};
207
- });
208
- },
209
- );
210
-
211
- XHRInterceptor.setResponseCallback(
212
- (status, timeout, response, responseURL, responseType, xhr) => {
213
- // $FlowFixMe[prop-missing]
214
- const xhrIndex = this._getRequestIndexByXHRID(getXHRId(xhr));
215
- if (xhrIndex === -1) {
216
- return;
217
- }
218
-
219
- this.setState(({requests}) => {
220
- const networkRequestInfo = requests[xhrIndex];
221
- networkRequestInfo.status = status;
222
- networkRequestInfo.timeout = timeout;
223
- networkRequestInfo.response = response;
224
- networkRequestInfo.responseURL = responseURL;
225
- networkRequestInfo.responseType = responseType;
226
-
227
- return {requests};
228
- });
229
- },
230
- );
231
-
232
- // Fire above callbacks.
233
- XHRInterceptor.enableInterception();
234
- }
235
-
236
- _enableWebSocketInterception(): void {
237
- if (WebSocketInterceptor.isInterceptorEnabled()) {
238
- return;
239
- }
240
- // Show the WebSocket request item in listView when 'connect' is called.
241
- WebSocketInterceptor.setConnectCallback(
242
- (url, protocols, options, socketId) => {
243
- const socketIndex = this.state.requests.length;
244
- this._socketIdMap[socketId] = socketIndex;
245
- const _webSocket: NetworkRequestInfo = {
246
- id: socketIndex,
247
- type: 'WebSocket',
248
- url: url,
249
- protocols: protocols,
250
- };
251
- this.setState(
252
- {
253
- requests: this.state.requests.concat(_webSocket),
254
- },
255
- this._indicateAdditionalRequests,
256
- );
257
- },
258
- );
259
-
260
- WebSocketInterceptor.setCloseCallback(
261
- (statusCode, closeReason, socketId) => {
262
- const socketIndex = this._socketIdMap[socketId];
263
- if (socketIndex === undefined) {
264
- return;
265
- }
266
- if (statusCode !== null && closeReason !== null) {
267
- this.setState(({requests}) => {
268
- const networkRequestInfo = requests[socketIndex];
269
- networkRequestInfo.status = statusCode;
270
- networkRequestInfo.closeReason = closeReason;
271
- return {requests};
272
- });
273
- }
274
- },
275
- );
276
-
277
- WebSocketInterceptor.setSendCallback((data, socketId) => {
278
- const socketIndex = this._socketIdMap[socketId];
279
- if (socketIndex === undefined) {
280
- return;
281
- }
282
-
283
- this.setState(({requests}) => {
284
- const networkRequestInfo = requests[socketIndex];
285
-
286
- if (!networkRequestInfo.messages) {
287
- networkRequestInfo.messages = '';
288
- }
289
- networkRequestInfo.messages += 'Sent: ' + JSON.stringify(data) + '\n';
290
-
291
- return {requests};
292
- });
293
- });
294
-
295
- WebSocketInterceptor.setOnMessageCallback((message, socketId) => {
296
- const socketIndex = this._socketIdMap[socketId];
297
- if (socketIndex === undefined) {
298
- return;
299
- }
300
-
301
- this.setState(({requests}) => {
302
- const networkRequestInfo = requests[socketIndex];
303
-
304
- if (!networkRequestInfo.messages) {
305
- networkRequestInfo.messages = '';
306
- }
307
- networkRequestInfo.messages +=
308
- 'Received: ' + JSON.stringify(message) + '\n';
309
-
310
- return {requests};
311
- });
312
- });
313
-
314
- WebSocketInterceptor.setOnCloseCallback((message, socketId) => {
315
- const socketIndex = this._socketIdMap[socketId];
316
- if (socketIndex === undefined) {
317
- return;
318
- }
319
-
320
- this.setState(({requests}) => {
321
- const networkRequestInfo = requests[socketIndex];
322
- networkRequestInfo.serverClose = message;
323
-
324
- return {requests};
325
- });
326
- });
327
-
328
- WebSocketInterceptor.setOnErrorCallback((message, socketId) => {
329
- const socketIndex = this._socketIdMap[socketId];
330
- if (socketIndex === undefined) {
331
- return;
332
- }
333
-
334
- this.setState(({requests}) => {
335
- const networkRequestInfo = requests[socketIndex];
336
- networkRequestInfo.serverError = message;
337
-
338
- return {requests};
339
- });
340
- });
341
-
342
- // Fire above callbacks.
343
- WebSocketInterceptor.enableInterception();
344
- }
345
-
346
- componentDidMount() {
347
- this._enableXHRInterception();
348
- this._enableWebSocketInterception();
349
- }
350
-
351
- componentWillUnmount() {
352
- XHRInterceptor.disableInterception();
353
- WebSocketInterceptor.disableInterception();
354
- }
355
-
356
- _renderItem = ({
357
- item,
358
- index,
359
- }: ListRenderItemInfo<NetworkRequestInfo>): React.MixedElement => {
360
- const tableRowViewStyle = [
361
- styles.tableRow,
362
- index % 2 === 1 ? styles.tableRowOdd : styles.tableRowEven,
363
- index === this.state.detailRowId && styles.tableRowPressed,
364
- ];
365
- const urlCellViewStyle = styles.urlCellView;
366
- const methodCellViewStyle = styles.methodCellView;
367
-
368
- return (
369
- <TouchableHighlight
370
- onPress={() => {
371
- this._pressRow(index);
372
- }}>
373
- <View>
374
- <View style={tableRowViewStyle}>
375
- <View style={urlCellViewStyle}>
376
- <Text style={styles.cellText} numberOfLines={1}>
377
- {item.url}
378
- </Text>
379
- </View>
380
- <View style={methodCellViewStyle}>
381
- <Text style={styles.cellText} numberOfLines={1}>
382
- {getTypeShortName(item.type)}
383
- </Text>
384
- </View>
385
- </View>
386
- </View>
387
- </TouchableHighlight>
388
- );
389
- };
390
-
391
- _renderItemDetail(id: number): React.Node {
392
- const requestItem = this.state.requests[id];
393
- const details = Object.keys(requestItem).map(key => {
394
- if (key === 'id') {
395
- return;
396
- }
397
- return (
398
- <View style={styles.detailViewRow} key={key}>
399
- <Text style={[styles.detailViewText, styles.detailKeyCellView]}>
400
- {key}
401
- </Text>
402
- <Text style={[styles.detailViewText, styles.detailValueCellView]}>
403
- {getStringByValue(requestItem[key])}
404
- </Text>
405
- </View>
406
- );
407
- });
408
-
409
- return (
410
- <View>
411
- <TouchableHighlight
412
- style={styles.closeButton}
413
- onPress={this._closeButtonClicked}>
414
- <View>
415
- <Text style={styles.closeButtonText}>v</Text>
416
- </View>
417
- </TouchableHighlight>
418
- <ScrollView
419
- style={styles.detailScrollView}
420
- ref={scrollRef => (this._detailScrollView = scrollRef)}>
421
- {details}
422
- </ScrollView>
423
- </View>
424
- );
425
- }
426
-
427
- _indicateAdditionalRequests = (): void => {
428
- if (this._requestsListView) {
429
- const distanceFromEndThreshold = LISTVIEW_CELL_HEIGHT * 2;
430
- const {offset, visibleLength, contentLength} =
431
- this._requestsListViewScrollMetrics;
432
- const distanceFromEnd = contentLength - visibleLength - offset;
433
- const isCloseToEnd = distanceFromEnd <= distanceFromEndThreshold;
434
- if (isCloseToEnd) {
435
- this._requestsListView.scrollToEnd();
436
- } else {
437
- this._requestsListView.flashScrollIndicators();
438
- }
439
- }
440
- };
441
-
442
- _captureRequestsListView = (listRef: ?FlatList<NetworkRequestInfo>): void => {
443
- this._requestsListView = listRef;
444
- };
445
-
446
- _requestsListViewOnScroll = (e: Object): void => {
447
- this._requestsListViewScrollMetrics.offset = e.nativeEvent.contentOffset.y;
448
- this._requestsListViewScrollMetrics.visibleLength =
449
- e.nativeEvent.layoutMeasurement.height;
450
- this._requestsListViewScrollMetrics.contentLength =
451
- e.nativeEvent.contentSize.height;
452
- };
453
-
454
- /**
455
- * Popup a scrollView to dynamically show detailed information of
456
- * the request, when pressing a row in the network flow listView.
457
- */
458
- _pressRow(rowId: number): void {
459
- this.setState({detailRowId: rowId}, this._scrollDetailToTop);
460
- }
461
-
462
- _scrollDetailToTop = (): void => {
463
- if (this._detailScrollView) {
464
- this._detailScrollView.scrollTo({
465
- y: 0,
466
- animated: false,
467
- });
468
- }
469
- };
470
-
471
- _closeButtonClicked = () => {
472
- this.setState({detailRowId: null});
473
- };
474
-
475
- _getRequestIndexByXHRID(index: number): number {
476
- if (index === undefined) {
477
- return -1;
478
- }
479
- const xhrIndex = this._xhrIdMap[index];
480
- if (xhrIndex === undefined) {
481
- return -1;
482
- } else {
483
- return xhrIndex;
484
- }
485
- }
486
-
487
- render(): React.Node {
488
- const {requests, detailRowId} = this.state;
489
-
490
- return (
491
- <View style={styles.container}>
492
- {detailRowId != null && this._renderItemDetail(detailRowId)}
493
- <View style={styles.listViewTitle}>
494
- {requests.length > 0 && (
495
- <View style={styles.tableRow}>
496
- <View style={styles.urlTitleCellView}>
497
- <Text style={styles.cellText} numberOfLines={1}>
498
- URL
499
- </Text>
500
- </View>
501
- <View style={styles.methodTitleCellView}>
502
- <Text style={styles.cellText} numberOfLines={1}>
503
- Type
504
- </Text>
505
- </View>
506
- </View>
507
- )}
508
- </View>
509
-
510
- <FlatList
511
- ref={this._captureRequestsListView}
512
- onScroll={this._requestsListViewOnScroll}
513
- style={styles.listView}
514
- data={requests}
515
- renderItem={this._renderItem}
516
- keyExtractor={keyExtractor}
517
- extraData={this.state}
518
- />
519
- </View>
520
- );
521
- }
522
- }
523
-
524
- const styles = StyleSheet.create({
525
- container: {
526
- paddingTop: 10,
527
- paddingBottom: 10,
528
- paddingLeft: 5,
529
- paddingRight: 5,
530
- },
531
- listViewTitle: {
532
- height: 20,
533
- },
534
- listView: {
535
- flex: 1,
536
- height: 60,
537
- },
538
- tableRow: {
539
- flexDirection: 'row',
540
- flex: 1,
541
- height: LISTVIEW_CELL_HEIGHT,
542
- },
543
- tableRowEven: {
544
- backgroundColor: '#555',
545
- },
546
- tableRowOdd: {
547
- backgroundColor: '#000',
548
- },
549
- tableRowPressed: {
550
- backgroundColor: '#3B5998',
551
- },
552
- cellText: {
553
- color: 'white',
554
- fontSize: 12,
555
- },
556
- methodTitleCellView: {
557
- height: 18,
558
- borderColor: '#DCD7CD',
559
- borderTopWidth: 1,
560
- borderBottomWidth: 1,
561
- borderRightWidth: 1,
562
- alignItems: 'center',
563
- justifyContent: 'center',
564
- backgroundColor: '#444',
565
- flex: 1,
566
- },
567
- urlTitleCellView: {
568
- height: 18,
569
- borderColor: '#DCD7CD',
570
- borderTopWidth: 1,
571
- borderBottomWidth: 1,
572
- borderLeftWidth: 1,
573
- borderRightWidth: 1,
574
- justifyContent: 'center',
575
- backgroundColor: '#444',
576
- flex: 5,
577
- paddingLeft: 3,
578
- },
579
- methodCellView: {
580
- height: 15,
581
- borderColor: '#DCD7CD',
582
- borderRightWidth: 1,
583
- alignItems: 'center',
584
- justifyContent: 'center',
585
- flex: 1,
586
- },
587
- urlCellView: {
588
- height: 15,
589
- borderColor: '#DCD7CD',
590
- borderLeftWidth: 1,
591
- borderRightWidth: 1,
592
- justifyContent: 'center',
593
- flex: 5,
594
- paddingLeft: 3,
595
- },
596
- detailScrollView: {
597
- flex: 1,
598
- height: 180,
599
- marginTop: 5,
600
- marginBottom: 5,
601
- },
602
- detailKeyCellView: {
603
- flex: 1.3,
604
- },
605
- detailValueCellView: {
606
- flex: 2,
607
- },
608
- detailViewRow: {
609
- flexDirection: 'row',
610
- paddingHorizontal: 3,
611
- },
612
- detailViewText: {
613
- color: 'white',
614
- fontSize: 11,
615
- },
616
- closeButtonText: {
617
- color: 'white',
618
- fontSize: 10,
619
- },
620
- closeButton: {
621
- marginTop: 5,
622
- backgroundColor: '#888',
623
- justifyContent: 'center',
624
- alignItems: 'center',
625
- },
626
- });
627
-
628
- export default NetworkOverlay;
@@ -1,66 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- * @format
9
- */
10
-
11
- 'use strict';
12
-
13
- import * as React from 'react';
14
-
15
- const View = require('../../../../../Libraries/Components/View/View').default;
16
- const StyleSheet =
17
- require('../../../../../Libraries/StyleSheet/StyleSheet').default;
18
- const Text = require('../../../../../Libraries/Text/Text').default;
19
- const PerformanceLogger =
20
- require('../../../../../Libraries/Utilities/GlobalPerformanceLogger').default;
21
-
22
- class PerformanceOverlay extends React.Component<{...}> {
23
- render(): React.Node {
24
- const perfLogs = PerformanceLogger.getTimespans();
25
- const items = [];
26
-
27
- for (const key in perfLogs) {
28
- if (perfLogs[key]?.totalTime) {
29
- const unit = key === 'BundleSize' ? 'b' : 'ms';
30
- items.push(
31
- <View style={styles.row} key={key}>
32
- <Text style={[styles.text, styles.label]}>{key}</Text>
33
- <Text style={[styles.text, styles.totalTime]}>
34
- {perfLogs[key].totalTime + unit}
35
- </Text>
36
- </View>,
37
- );
38
- }
39
- }
40
-
41
- return <View style={styles.container}>{items}</View>;
42
- }
43
- }
44
-
45
- const styles = StyleSheet.create({
46
- container: {
47
- height: 100,
48
- paddingTop: 10,
49
- },
50
- label: {
51
- flex: 1,
52
- },
53
- row: {
54
- flexDirection: 'row',
55
- paddingHorizontal: 10,
56
- },
57
- text: {
58
- color: 'white',
59
- fontSize: 12,
60
- },
61
- totalTime: {
62
- paddingRight: 100,
63
- },
64
- });
65
-
66
- export default PerformanceOverlay;