Skip to content

Commit 942e7f2

Browse files
motiz88meta-codesync[bot]
authored andcommitted
Add LogBox-styled error overlay
Summary: Replace the legacy red-on-black RedBox design with a LogBox-inspired design for RedBox 2.0: charcoal background, salmon header bar, structured call stack, 3-button footer, full-screen view with no animated transition. Gated behind `redBoxV2IOS`. This diff is just for the low-hanging fruit - setting up the split implementation and borrowing the broad visual style of LogBox. Further up this stack we will port more functionality and improve on this baseline. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D98115368
1 parent e2a0746 commit 942e7f2

5 files changed

Lines changed: 587 additions & 22 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
8+
#import <React/RCTDefines.h>
9+
#import <UIKit/UIKit.h>
10+
11+
#if RCT_DEV_MENU
12+
13+
@class RCTJSStackFrame;
14+
15+
@protocol RCTRedBoxControllerActionDelegate <NSObject>
16+
17+
- (void)redBoxController:(UIViewController *)redBoxController openStackFrameInEditor:(RCTJSStackFrame *)stackFrame;
18+
- (void)reloadFromRedBoxController:(UIViewController *)redBoxController;
19+
- (void)loadExtraDataViewController;
20+
21+
@end
22+
23+
@protocol RCTRedBoxControlling <NSObject>
24+
25+
@property (nonatomic, weak) id<RCTRedBoxControllerActionDelegate> actionDelegate;
26+
27+
- (void)showErrorMessage:(NSString *)message
28+
withStack:(NSArray<RCTJSStackFrame *> *)stack
29+
isUpdate:(BOOL)isUpdate
30+
errorCookie:(int)errorCookie;
31+
32+
- (void)dismiss;
33+
34+
@end
35+
36+
#endif

packages/react-native/React/CoreModules/RCTRedBox.mm

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
#import <React/RCTRedBoxExtraDataViewController.h>
1717
#import <React/RCTReloadCommand.h>
1818
#import <React/RCTUtils.h>
19+
#import <react/featureflags/ReactNativeFeatureFlags.h>
1920

2021
#import "CoreModulesPlugins.h"
22+
#import "RCTRedBox+Internal.h"
23+
#import "RCTRedBox2Controller+Internal.h"
2124
#import "RCTRedBoxController+Internal.h"
2225

2326
#if RCT_DEV_MENU
@@ -30,7 +33,7 @@ @interface RCTRedBox () <
3033
@end
3134

3235
@implementation RCTRedBox {
33-
RCTRedBoxController *_controller;
36+
id<RCTRedBoxControlling> _controller;
3437
NSMutableArray<id<RCTErrorCustomizer>> *_errorCustomizers;
3538
RCTRedBoxExtraDataViewController *_extraDataViewController;
3639
NSMutableArray<NSString *> *_customButtonTitles;
@@ -178,14 +181,20 @@ - (void)showErrorMessage:(NSString *)message
178181
[[self->_moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"collectRedBoxExtraData"
179182
body:nil];
180183
#pragma clang diagnostic pop
181-
if (!self->_controller) {
182-
self->_controller = [[RCTRedBoxController alloc] initWithCustomButtonTitles:self->_customButtonTitles
183-
customButtonHandlers:self->_customButtonHandlers];
184-
self->_controller.actionDelegate = self;
185-
}
186184

187185
RCTErrorInfo *errorInfo = [[RCTErrorInfo alloc] initWithErrorMessage:message stack:stack];
188186
errorInfo = [self _customizeError:errorInfo];
187+
188+
if (self->_controller == nullptr) {
189+
if (facebook::react::ReactNativeFeatureFlags::redBoxV2IOS()) {
190+
self->_controller = [[RCTRedBox2Controller alloc] initWithCustomButtonTitles:self->_customButtonTitles
191+
customButtonHandlers:self->_customButtonHandlers];
192+
} else {
193+
self->_controller = [[RCTRedBoxController alloc] initWithCustomButtonTitles:self->_customButtonTitles
194+
customButtonHandlers:self->_customButtonHandlers];
195+
}
196+
self->_controller.actionDelegate = self;
197+
}
189198
[self->_controller showErrorMessage:errorInfo.errorMessage
190199
withStack:errorInfo.stack
191200
isUpdate:isUpdate
@@ -196,9 +205,10 @@ - (void)showErrorMessage:(NSString *)message
196205
- (void)loadExtraDataViewController
197206
{
198207
dispatch_async(dispatch_get_main_queue(), ^{
208+
UIViewController *controller = static_cast<UIViewController *>(self->_controller);
199209
// Make sure the CMD+E shortcut doesn't call this twice
200-
if (self->_extraDataViewController != nil && ![self->_controller presentedViewController]) {
201-
[self->_controller presentViewController:self->_extraDataViewController animated:YES completion:nil];
210+
if (self->_extraDataViewController != nil && ([controller presentedViewController] == nullptr)) {
211+
[controller presentViewController:self->_extraDataViewController animated:YES completion:nil];
202212
}
203213
});
204214
}
@@ -220,7 +230,7 @@ - (void)invalidate
220230
[self dismiss];
221231
}
222232

223-
- (void)redBoxController:(__unused RCTRedBoxController *)redBoxController
233+
- (void)redBoxController:(__unused UIViewController *)redBoxController
224234
openStackFrameInEditor:(RCTJSStackFrame *)stackFrame
225235
{
226236
NSURL *const bundleURL = _overrideBundleURL ?: _bundleManager.bundleURL;
@@ -247,7 +257,7 @@ - (void)reload
247257
[self reloadFromRedBoxController:nil];
248258
}
249259

250-
- (void)reloadFromRedBoxController:(__unused RCTRedBoxController *)redBoxController
260+
- (void)reloadFromRedBoxController:(__unused UIViewController *)redBoxController
251261
{
252262
if (_overrideReloadAction) {
253263
_overrideReloadAction();
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
8+
#import <React/RCTDefines.h>
9+
10+
#import "RCTRedBox+Internal.h"
11+
12+
#if RCT_DEV_MENU
13+
14+
using RCTRedBox2ButtonPressHandler = void (^)(void);
15+
16+
@interface RCTRedBox2Controller : UIViewController <RCTRedBoxControlling, UITableViewDelegate, UITableViewDataSource>
17+
18+
@property (nonatomic, weak) id<RCTRedBoxControllerActionDelegate> actionDelegate;
19+
20+
- (instancetype)initWithCustomButtonTitles:(NSArray<NSString *> *)customButtonTitles
21+
customButtonHandlers:(NSArray<RCTRedBox2ButtonPressHandler> *)customButtonHandlers;
22+
23+
- (void)showErrorMessage:(NSString *)message
24+
withStack:(NSArray<RCTJSStackFrame *> *)stack
25+
isUpdate:(BOOL)isUpdate
26+
errorCookie:(int)errorCookie;
27+
28+
- (void)dismiss;
29+
@end
30+
31+
#endif

0 commit comments

Comments
 (0)