From f59b2e699b281e4079bb8ca86fe83115050f3a4f Mon Sep 17 00:00:00 2001 From: Vitali Zaidman Date: Mon, 23 Feb 2026 05:32:58 -0800 Subject: [PATCH 1/2] display same bundle progress as metro Differential Revision: D93737736 --- packages/react-native/React/Base/RCTJavaScriptLoader.h | 1 + packages/react-native/React/Base/RCTJavaScriptLoader.mm | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/react-native/React/Base/RCTJavaScriptLoader.h b/packages/react-native/React/Base/RCTJavaScriptLoader.h index 9893e693166..f6fcfc58a3b 100755 --- a/packages/react-native/React/Base/RCTJavaScriptLoader.h +++ b/packages/react-native/React/Base/RCTJavaScriptLoader.h @@ -33,6 +33,7 @@ NS_ENUM(NSInteger){ @property (nonatomic, copy) NSString *status; @property (strong, nonatomic) NSNumber *done; @property (strong, nonatomic) NSNumber *total; +@property (strong, nonatomic) NSNumber *percent; @end diff --git a/packages/react-native/React/Base/RCTJavaScriptLoader.mm b/packages/react-native/React/Base/RCTJavaScriptLoader.mm index 5e8da828324..5f7d6e9b5ef 100755 --- a/packages/react-native/React/Base/RCTJavaScriptLoader.mm +++ b/packages/react-native/React/Base/RCTJavaScriptLoader.mm @@ -53,8 +53,9 @@ - (NSString *)description { NSMutableString *desc = [NSMutableString new]; [desc appendString:_status ?: @"Bundling"]; - - if ([_total integerValue] > 0 && [_done integerValue] > [_total integerValue]) { + if (_percent != nil) { + [desc appendFormat:@" %ld%%", (long)[_percent integerValue]]; + } else if ([_total integerValue] > 0 && [_done integerValue] > [_total integerValue]) { [desc appendFormat:@" %ld%%", (long)100]; } else if ([_total integerValue] > 0) { [desc appendFormat:@" %ld%%", (long)(100 * [_done integerValue] / [_total integerValue])]; @@ -348,6 +349,9 @@ static void attemptAsynchronousLoadOfBundleAtURL( progress.status = info[@"status"]; progress.done = info[@"done"]; progress.total = info[@"total"]; + if (info[@"percent"] != nil) { + progress.percent = info[@"percent"]; + } return progress; } From 44f206171911439a32b91c5f2416d94e53d43f20 Mon Sep 17 00:00:00 2001 From: Vitali Zaidman Date: Mon, 23 Feb 2026 05:41:18 -0800 Subject: [PATCH 2/2] sync bundling progress between Metro cli and app hints (#55655) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/55655 Changelog: [Android][Fixed] sync bundling progress between Metro cli and app hints Reviewed By: cortinico Differential Revision: D93738119 --- .../ReactAndroid/api/ReactAndroid.api | 6 ++--- .../react/devsupport/BundleDownloader.kt | 23 +++++++++++-------- .../DefaultDevLoadingViewImplementation.kt | 5 ++-- .../react/devsupport/DevSupportManagerBase.kt | 10 ++++---- .../interfaces/DevBundleDownloadListener.kt | 2 +- .../interfaces/DevLoadingViewManager.kt | 2 +- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 005309b0d93..a5f363904f5 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1864,7 +1864,7 @@ public final class com/facebook/react/devsupport/DefaultDevLoadingViewImplementa public fun hide ()V public fun showMessage (Ljava/lang/String;)V public fun showMessage (Ljava/lang/String;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/Boolean;)V - public fun updateProgress (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;)V + public fun updateProgress (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V } public final class com/facebook/react/devsupport/DefaultDevLoadingViewImplementation$Companion { @@ -2108,7 +2108,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/BundleL public abstract interface class com/facebook/react/devsupport/interfaces/DevBundleDownloadListener { public abstract fun onFailure (Ljava/lang/Exception;)V - public abstract fun onProgress (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;)V + public abstract fun onProgress (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V public abstract fun onSuccess ()V } @@ -2116,7 +2116,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevLoad public abstract fun hide ()V public abstract fun showMessage (Ljava/lang/String;)V public abstract fun showMessage (Ljava/lang/String;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/Boolean;)V - public abstract fun updateProgress (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;)V + public abstract fun updateProgress (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;)V } public abstract interface class com/facebook/react/devsupport/interfaces/DevOptionHandler { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BundleDownloader.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BundleDownloader.kt index c7b814a4299..e315d5a2d44 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BundleDownloader.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BundleDownloader.kt @@ -169,12 +169,12 @@ public class BundleDownloader public constructor(private val client: OkHttpClien DebugServerException( (""" Error while reading multipart response. - + Response body was empty: ${response.code()} - + URL: $url - - + + """ .trimIndent()) ) @@ -231,7 +231,11 @@ public class BundleDownloader public constructor(private val client: OkHttpClien if (progress.has("total")) { total = progress.getInt("total") } - callback.onProgress(status, done, total) + var percent: Int? = null + if (progress.has("percent")) { + percent = progress.getInt("percent") + } + callback.onProgress(status, done, total, percent) } catch (e: JSONException) { FLog.e(ReactConstants.TAG, "Error parsing progress JSON. $e") } @@ -248,6 +252,7 @@ public class BundleDownloader public constructor(private val client: OkHttpClien "Downloading", (loaded / 1024).toInt(), (total / 1024).toInt(), + null, ) } } @@ -258,12 +263,12 @@ public class BundleDownloader public constructor(private val client: OkHttpClien DebugServerException( (""" Error while reading multipart response. - + Response code: ${response.code()} - + URL: $url - - + + """ .trimIndent()) ) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevLoadingViewImplementation.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevLoadingViewImplementation.kt index 8271dfc12cc..ae2753ef44c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevLoadingViewImplementation.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevLoadingViewImplementation.kt @@ -51,13 +51,14 @@ public class DefaultDevLoadingViewImplementation( } } - override fun updateProgress(status: String?, done: Int?, total: Int?) { + override fun updateProgress(status: String?, done: Int?, total: Int?, percent: Int?) { if (!isEnabled) { return } UiThreadUtil.runOnUiThread { val percentage = - if (done != null && total != null && total > 0) + if (percent != null) String.format(Locale.getDefault(), " %d%%", percent) + else if (done != null && total != null && total > 0) String.format(Locale.getDefault(), " %.1f%%", done.toFloat() / total * 100) else "" devLoadingView?.text = diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt index 543ed13f937..0608c07b78b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt @@ -789,8 +789,8 @@ public abstract class DevSupportManagerBase( callback.onSuccess(bundleLoader) } - override fun onProgress(status: String?, done: Int?, total: Int?) { - devLoadingViewManager?.updateProgress(status, done, total) + override fun onProgress(status: String?, done: Int?, total: Int?, percent: Int?) { + devLoadingViewManager?.updateProgress(status, done, total, percent) } override fun onFailure(cause: Exception) { @@ -856,9 +856,9 @@ public abstract class DevSupportManagerBase( callback.onSuccess() } - override fun onProgress(status: String?, done: Int?, total: Int?) { - devLoadingViewManager?.updateProgress(status, done, total) - devBundleDownloadListener?.onProgress(status, done, total) + override fun onProgress(status: String?, done: Int?, total: Int?, percent: Int?) { + devLoadingViewManager?.updateProgress(status, done, total, percent) + devBundleDownloadListener?.onProgress(status, done, total, percent) } override fun onFailure(cause: Exception) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevBundleDownloadListener.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevBundleDownloadListener.kt index 0dcf6a9c51d..c3557ec9ece 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevBundleDownloadListener.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevBundleDownloadListener.kt @@ -10,7 +10,7 @@ package com.facebook.react.devsupport.interfaces public interface DevBundleDownloadListener { public fun onSuccess() - public fun onProgress(status: String?, done: Int?, total: Int?) + public fun onProgress(status: String?, done: Int?, total: Int?, percent: Int?) public fun onFailure(cause: Exception) } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevLoadingViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevLoadingViewManager.kt index 600941aabb0..e79cc8e095c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevLoadingViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevLoadingViewManager.kt @@ -18,7 +18,7 @@ public interface DevLoadingViewManager { dismissButton: Boolean?, ) - public fun updateProgress(status: String?, done: Int?, total: Int?) + public fun updateProgress(status: String?, done: Int?, total: Int?, percent: Int?) public fun hide() }