Added toggle items to dev menu
Reviewed By: @tadeuzagallo Differential Revision: D2424595
This commit is contained in:
parent
eb48759675
commit
515d5a5f4b
|
@ -225,7 +225,7 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
||||||
}
|
}
|
||||||
|
|
||||||
__block BOOL isProfiling = NO;
|
__block BOOL isProfiling = NO;
|
||||||
[bridge.devMenu addItem:@"Profile" handler:^{
|
[bridge.devMenu addItem:[RCTDevMenuItem buttonItemWithTitle:@"Profile" handler:^{
|
||||||
if (isProfiling) {
|
if (isProfiling) {
|
||||||
NSString *outputFile = [NSTemporaryDirectory() stringByAppendingPathComponent:@"cpu_profile.json"];
|
NSString *outputFile = [NSTemporaryDirectory() stringByAppendingPathComponent:@"cpu_profile.json"];
|
||||||
nativeProfilerEnd(context, "profile", outputFile.UTF8String);
|
nativeProfilerEnd(context, "profile", outputFile.UTF8String);
|
||||||
|
@ -238,7 +238,7 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
||||||
nativeProfilerStart(context, "profile");
|
nativeProfilerStart(context, "profile");
|
||||||
}
|
}
|
||||||
isProfiling = !isProfiling;
|
isProfiling = !isProfiling;
|
||||||
}];
|
}]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#import "RCTBridge.h"
|
#import "RCTBridge.h"
|
||||||
#import "RCTBridgeModule.h"
|
#import "RCTBridgeModule.h"
|
||||||
|
|
||||||
|
@class RCTDevMenuItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Developer menu, useful for exposing extra functionality when debugging.
|
* Developer menu, useful for exposing extra functionality when debugging.
|
||||||
*/
|
*/
|
||||||
|
@ -35,7 +37,7 @@
|
||||||
@property (nonatomic, assign) BOOL liveReloadEnabled;
|
@property (nonatomic, assign) BOOL liveReloadEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the FPS monitor for the JS and Main threads
|
* Shows the FPS monitor for the JS and Main threads.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, assign) BOOL showFPS;
|
@property (nonatomic, assign) BOOL showFPS;
|
||||||
|
|
||||||
|
@ -50,14 +52,44 @@
|
||||||
*/
|
*/
|
||||||
- (void)reload;
|
- (void)reload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated. Use the `-addItem:` method instead.
|
||||||
|
*/
|
||||||
|
- (void)addItem:(NSString *)title
|
||||||
|
handler:(void(^)(void))handler DEPRECATED_ATTRIBUTE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add custom item to the development menu. The handler will be called
|
* Add custom item to the development menu. The handler will be called
|
||||||
* when user selects the item.
|
* when user selects the item.
|
||||||
*/
|
*/
|
||||||
- (void)addItem:(NSString *)title handler:(dispatch_block_t)handler;
|
- (void)addItem:(RCTDevMenuItem *)item;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Developer menu item, used to expose additional functionality via the menu.
|
||||||
|
*/
|
||||||
|
@interface RCTDevMenuItem : NSObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates an item with a simple push-button interface, used to trigger an
|
||||||
|
* action.
|
||||||
|
*/
|
||||||
|
+ (instancetype)buttonItemWithTitle:(NSString *)title
|
||||||
|
handler:(void(^)(void))handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates an item with a toggle behavior. The key is used to store the
|
||||||
|
* state of the toggle. For toggle items, the handler will be called immediately
|
||||||
|
* after the item is added if the item was already selected when the module was
|
||||||
|
* last loaded.
|
||||||
|
*/
|
||||||
|
+ (instancetype)toggleItemWithKey:(NSString *)key
|
||||||
|
title:(NSString *)title
|
||||||
|
selectedTitle:(NSString *)selectedTitle
|
||||||
|
handler:(void(^)(BOOL selected))handler;
|
||||||
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This category makes the developer menu instance available via the
|
* This category makes the developer menu instance available via the
|
||||||
* RCTBridge, which is useful for any class that needs to access the menu.
|
* RCTBridge, which is useful for any class that needs to access the menu.
|
||||||
|
|
|
@ -44,31 +44,88 @@ static NSString *const RCTDevMenuSettingsKey = @"RCTDevMenu";
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface RCTDevMenuItem : NSObject
|
typedef NS_ENUM(NSInteger, RCTDevMenuType) {
|
||||||
|
RCTDevMenuTypeButton,
|
||||||
|
RCTDevMenuTypeToggle
|
||||||
|
};
|
||||||
|
|
||||||
@property (nonatomic, copy) NSString *title;
|
@interface RCTDevMenuItem ()
|
||||||
@property (nonatomic, copy) dispatch_block_t handler;
|
|
||||||
|
|
||||||
- (instancetype)initWithTitle:(NSString *)title handler:(dispatch_block_t)handler NS_DESIGNATED_INITIALIZER;
|
@property (nonatomic, assign, readonly) RCTDevMenuType type;
|
||||||
|
@property (nonatomic, copy, readonly) NSString *key;
|
||||||
|
@property (nonatomic, copy, readonly) NSString *title;
|
||||||
|
@property (nonatomic, copy, readonly) NSString *selectedTitle;
|
||||||
|
@property (nonatomic, copy) id value;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation RCTDevMenuItem
|
@implementation RCTDevMenuItem
|
||||||
|
{
|
||||||
|
id _handler; // block
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithTitle:(NSString *)title handler:(dispatch_block_t)handler
|
- (instancetype)initWithType:(RCTDevMenuType)type
|
||||||
|
key:(NSString *)key
|
||||||
|
title:(NSString *)title
|
||||||
|
selectedTitle:(NSString *)selectedTitle
|
||||||
|
handler:(id /* block */)handler
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
_type = type;
|
||||||
|
_key = [key copy];
|
||||||
_title = [title copy];
|
_title = [title copy];
|
||||||
|
_selectedTitle = [selectedTitle copy];
|
||||||
_handler = [handler copy];
|
_handler = [handler copy];
|
||||||
|
_value = nil;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||||
|
|
||||||
|
+ (instancetype)buttonItemWithTitle:(NSString *)title
|
||||||
|
handler:(void (^)(void))handler
|
||||||
|
{
|
||||||
|
return [[self alloc] initWithType:RCTDevMenuTypeButton
|
||||||
|
key:nil
|
||||||
|
title:title
|
||||||
|
selectedTitle:nil
|
||||||
|
handler:handler];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)toggleItemWithKey:(NSString *)key
|
||||||
|
title:(NSString *)title
|
||||||
|
selectedTitle:(NSString *)selectedTitle
|
||||||
|
handler:(void (^)(BOOL selected))handler
|
||||||
|
{
|
||||||
|
return [[self alloc] initWithType:RCTDevMenuTypeToggle
|
||||||
|
key:key
|
||||||
|
title:title
|
||||||
|
selectedTitle:selectedTitle
|
||||||
|
handler:handler];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)callHandler
|
||||||
|
{
|
||||||
|
switch (_type) {
|
||||||
|
case RCTDevMenuTypeButton: {
|
||||||
|
if (_handler) {
|
||||||
|
((void(^)())_handler)();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RCTDevMenuTypeToggle: {
|
||||||
|
if (_handler) {
|
||||||
|
((void(^)(BOOL selected))_handler)([_value boolValue]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface RCTDevMenu () <RCTBridgeModule, UIActionSheetDelegate>
|
@interface RCTDevMenu () <RCTBridgeModule, UIActionSheetDelegate, RCTInvalidating>
|
||||||
|
|
||||||
@property (nonatomic, strong) Class executorClass;
|
@property (nonatomic, strong) Class executorClass;
|
||||||
|
|
||||||
|
@ -125,15 +182,42 @@ RCT_EXPORT_MODULE()
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
_defaults = [NSUserDefaults standardUserDefaults];
|
_defaults = [NSUserDefaults standardUserDefaults];
|
||||||
_settings = [NSMutableDictionary new];
|
_settings = [[NSMutableDictionary alloc] initWithDictionary:[_defaults objectForKey:RCTDevMenuSettingsKey]];
|
||||||
_extraMenuItems = [NSMutableArray array];
|
_extraMenuItems = [NSMutableArray new];
|
||||||
|
|
||||||
|
__weak RCTDevMenu *weakSelf = self;
|
||||||
|
|
||||||
|
[_extraMenuItems addObject:[RCTDevMenuItem toggleItemWithKey:@"showFPS"
|
||||||
|
title:@"Show FPS Monitor"
|
||||||
|
selectedTitle:@"Hide FPS Monitor"
|
||||||
|
handler:^(BOOL showFPS)
|
||||||
|
{
|
||||||
|
RCTDevMenu *strongSelf = weakSelf;
|
||||||
|
if (strongSelf) {
|
||||||
|
strongSelf->_showFPS = showFPS;
|
||||||
|
if (showFPS) {
|
||||||
|
[strongSelf.bridge.perfStats show];
|
||||||
|
} else {
|
||||||
|
[strongSelf.bridge.perfStats hide];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]];
|
||||||
|
|
||||||
|
[_extraMenuItems addObject:[RCTDevMenuItem toggleItemWithKey:@"showInspector"
|
||||||
|
title:@"Show Inspector"
|
||||||
|
selectedTitle:@"Hide Inspector"
|
||||||
|
handler:^(__unused BOOL enabled)
|
||||||
|
{
|
||||||
|
[weakSelf.bridge.eventDispatcher sendDeviceEventWithName:@"toggleElementInspector" body:nil];
|
||||||
|
}]];
|
||||||
|
|
||||||
// Delay setup until after Bridge init
|
// Delay setup until after Bridge init
|
||||||
[self settingsDidChange];
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[weakSelf updateSettings:_settings];
|
||||||
|
});
|
||||||
|
|
||||||
#if TARGET_IPHONE_SIMULATOR
|
#if TARGET_IPHONE_SIMULATOR
|
||||||
|
|
||||||
__weak RCTDevMenu *weakSelf = self;
|
|
||||||
RCTKeyCommands *commands = [RCTKeyCommands sharedInstance];
|
RCTKeyCommands *commands = [RCTKeyCommands sharedInstance];
|
||||||
|
|
||||||
// Toggle debug menu
|
// Toggle debug menu
|
||||||
|
@ -173,14 +257,31 @@ RCT_EXPORT_MODULE()
|
||||||
{
|
{
|
||||||
// Needed to prevent a race condition when reloading
|
// Needed to prevent a race condition when reloading
|
||||||
__weak RCTDevMenu *weakSelf = self;
|
__weak RCTDevMenu *weakSelf = self;
|
||||||
|
NSDictionary *settings = [_defaults objectForKey:RCTDevMenuSettingsKey];
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[weakSelf updateSettings];
|
[weakSelf updateSettings:settings];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateSettings
|
/**
|
||||||
|
* This method loads the settings from NSUserDefaults and overrides any local
|
||||||
|
* settings with them. It should only be called on app launch, or after the app
|
||||||
|
* has returned from the background, when the settings might have been edited
|
||||||
|
* outside of the app.
|
||||||
|
*/
|
||||||
|
- (void)updateSettings:(NSDictionary *)settings
|
||||||
{
|
{
|
||||||
NSDictionary *settings = [_defaults objectForKey:RCTDevMenuSettingsKey];
|
// Fire handlers for items whose values have changed
|
||||||
|
for (RCTDevMenuItem *item in _extraMenuItems) {
|
||||||
|
if (item.key) {
|
||||||
|
id value = settings[item.key];
|
||||||
|
if (value != item.value && ![value isEqual:item.value]) {
|
||||||
|
item.value = value;
|
||||||
|
[item callHandler];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ([settings isEqualToDictionary:_settings]) {
|
if ([settings isEqualToDictionary:_settings]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -193,6 +294,39 @@ RCT_EXPORT_MODULE()
|
||||||
self.executorClass = NSClassFromString(_settings[@"executorClass"]);
|
self.executorClass = NSClassFromString(_settings[@"executorClass"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This updates a particular setting, and then saves the settings. Because all
|
||||||
|
* settings are overwritten by this, it's important that this is not called
|
||||||
|
* before settings have been loaded initially, otherwise the other settings
|
||||||
|
* will be reset.
|
||||||
|
*/
|
||||||
|
- (void)updateSetting:(NSString *)name value:(id)value
|
||||||
|
{
|
||||||
|
// Fire handler for item whose values has changed
|
||||||
|
for (RCTDevMenuItem *item in _extraMenuItems) {
|
||||||
|
if ([item.key isEqualToString:name]) {
|
||||||
|
if (value != item.value && ![value isEqual:item.value]) {
|
||||||
|
item.value = value;
|
||||||
|
[item callHandler];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the setting
|
||||||
|
id currentValue = _settings[name];
|
||||||
|
if (currentValue == value || [currentValue isEqual:value]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
_settings[name] = value;
|
||||||
|
} else {
|
||||||
|
[_settings removeObjectForKey:name];
|
||||||
|
}
|
||||||
|
[_defaults setObject:_settings forKey:RCTDevMenuSettingsKey];
|
||||||
|
[_defaults synchronize];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)jsLoaded:(NSNotification *)notification
|
- (void)jsLoaded:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
if (notification.userInfo[@"bridge"] != _bridge) {
|
if (notification.userInfo[@"bridge"] != _bridge) {
|
||||||
|
@ -220,31 +354,22 @@ RCT_EXPORT_MODULE()
|
||||||
self.profilingEnabled = _profilingEnabled;
|
self.profilingEnabled = _profilingEnabled;
|
||||||
self.liveReloadEnabled = _liveReloadEnabled;
|
self.liveReloadEnabled = _liveReloadEnabled;
|
||||||
self.executorClass = _executorClass;
|
self.executorClass = _executorClass;
|
||||||
|
|
||||||
|
// Inspector can only be shown after JS has loaded
|
||||||
|
if ([_settings[@"showInspector"] boolValue]) {
|
||||||
|
[self.bridge.eventDispatcher sendDeviceEventWithName:@"toggleElementInspector" body:nil];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)invalidate
|
||||||
{
|
{
|
||||||
|
_presentedItems = nil;
|
||||||
[_updateTask cancel];
|
[_updateTask cancel];
|
||||||
[_actionSheet dismissWithClickedButtonIndex:_actionSheet.cancelButtonIndex animated:YES];
|
[_actionSheet dismissWithClickedButtonIndex:_actionSheet.cancelButtonIndex animated:YES];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateSetting:(NSString *)name value:(id)value
|
|
||||||
{
|
|
||||||
id currentValue = _settings[name];
|
|
||||||
if (currentValue == value || [currentValue isEqual:value]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (value) {
|
|
||||||
_settings[name] = value;
|
|
||||||
} else {
|
|
||||||
[_settings removeObjectForKey:name];
|
|
||||||
}
|
|
||||||
[_defaults setObject:_settings forKey:RCTDevMenuSettingsKey];
|
|
||||||
[_defaults synchronize];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)showOnShake
|
- (void)showOnShake
|
||||||
{
|
{
|
||||||
if (_shakeToShow) {
|
if (_shakeToShow) {
|
||||||
|
@ -262,22 +387,34 @@ RCT_EXPORT_MODULE()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addItem:(NSString *)title handler:(dispatch_block_t)handler
|
- (void)addItem:(NSString *)title handler:(void(^)(void))handler
|
||||||
{
|
{
|
||||||
[_extraMenuItems addObject:[[RCTDevMenuItem alloc] initWithTitle:title handler:handler]];
|
[self addItem:[RCTDevMenuItem buttonItemWithTitle:title handler:handler]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addItem:(RCTDevMenuItem *)item
|
||||||
|
{
|
||||||
|
[_extraMenuItems addObject:item];
|
||||||
|
|
||||||
|
// Fire handler for items whose saved value doesn't match the default
|
||||||
|
[self settingsDidChange];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)menuItems
|
- (NSArray *)menuItems
|
||||||
{
|
{
|
||||||
NSMutableArray *items = [NSMutableArray array];
|
NSMutableArray *items = [NSMutableArray new];
|
||||||
|
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:@"Reload" handler:^{
|
// Add built-in items
|
||||||
[self reload];
|
|
||||||
|
__weak RCTDevMenu *weakSelf = self;
|
||||||
|
|
||||||
|
[items addObject:[RCTDevMenuItem buttonItemWithTitle:@"Reload" handler:^{
|
||||||
|
[weakSelf reload];
|
||||||
}]];
|
}]];
|
||||||
|
|
||||||
Class chromeExecutorClass = NSClassFromString(@"RCTWebSocketExecutor");
|
Class chromeExecutorClass = NSClassFromString(@"RCTWebSocketExecutor");
|
||||||
if (!chromeExecutorClass) {
|
if (!chromeExecutorClass) {
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:@"Chrome Debugger Unavailable" handler:^{
|
[items addObject:[RCTDevMenuItem buttonItemWithTitle:@"Chrome Debugger Unavailable" handler:^{
|
||||||
[[[UIAlertView alloc] initWithTitle:@"Chrome Debugger Unavailable"
|
[[[UIAlertView alloc] initWithTitle:@"Chrome Debugger Unavailable"
|
||||||
message:@"You need to include the RCTWebSocket library to enable Chrome debugging"
|
message:@"You need to include the RCTWebSocket library to enable Chrome debugging"
|
||||||
delegate:nil
|
delegate:nil
|
||||||
|
@ -286,37 +423,28 @@ RCT_EXPORT_MODULE()
|
||||||
}]];
|
}]];
|
||||||
} else {
|
} else {
|
||||||
BOOL isDebuggingInChrome = _executorClass && _executorClass == chromeExecutorClass;
|
BOOL isDebuggingInChrome = _executorClass && _executorClass == chromeExecutorClass;
|
||||||
NSString *debugTitleChrome = isDebuggingInChrome ? @"Stop Chrome Debugging" : @"Debug in Chrome";
|
NSString *debugTitleChrome = isDebuggingInChrome ? @"Disable Chrome Debugging" : @"Debug in Chrome";
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:debugTitleChrome handler:^{
|
[items addObject:[RCTDevMenuItem buttonItemWithTitle:debugTitleChrome handler:^{
|
||||||
self.executorClass = isDebuggingInChrome ? Nil : chromeExecutorClass;
|
weakSelf.executorClass = isDebuggingInChrome ? Nil : chromeExecutorClass;
|
||||||
}]];
|
}]];
|
||||||
}
|
}
|
||||||
|
|
||||||
Class safariExecutorClass = NSClassFromString(@"RCTWebViewExecutor");
|
Class safariExecutorClass = NSClassFromString(@"RCTWebViewExecutor");
|
||||||
BOOL isDebuggingInSafari = _executorClass && _executorClass == safariExecutorClass;
|
BOOL isDebuggingInSafari = _executorClass && _executorClass == safariExecutorClass;
|
||||||
NSString *debugTitleSafari = isDebuggingInSafari ? @"Stop Safari Debugging" : @"Debug in Safari";
|
NSString *debugTitleSafari = isDebuggingInSafari ? @"Disable Safari Debugging" : @"Debug in Safari";
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:debugTitleSafari handler:^{
|
[items addObject:[RCTDevMenuItem buttonItemWithTitle:debugTitleSafari handler:^{
|
||||||
self.executorClass = isDebuggingInSafari ? Nil : safariExecutorClass;
|
weakSelf.executorClass = isDebuggingInSafari ? Nil : safariExecutorClass;
|
||||||
}]];
|
|
||||||
|
|
||||||
NSString *fpsMonitor = _showFPS ? @"Hide FPS Monitor" : @"Show FPS Monitor";
|
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:fpsMonitor handler:^{
|
|
||||||
self.showFPS = !_showFPS;
|
|
||||||
}]];
|
|
||||||
|
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:@"Inspect Element" handler:^{
|
|
||||||
[_bridge.eventDispatcher sendDeviceEventWithName:@"toggleElementInspector" body:nil];
|
|
||||||
}]];
|
}]];
|
||||||
|
|
||||||
if (_liveReloadURL) {
|
if (_liveReloadURL) {
|
||||||
NSString *liveReloadTitle = _liveReloadEnabled ? @"Disable Live Reload" : @"Enable Live Reload";
|
NSString *liveReloadTitle = _liveReloadEnabled ? @"Disable Live Reload" : @"Enable Live Reload";
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:liveReloadTitle handler:^{
|
[items addObject:[RCTDevMenuItem buttonItemWithTitle:liveReloadTitle handler:^{
|
||||||
self.liveReloadEnabled = !_liveReloadEnabled;
|
weakSelf.liveReloadEnabled = !_liveReloadEnabled;
|
||||||
}]];
|
}]];
|
||||||
|
|
||||||
NSString *profilingTitle = RCTProfileIsProfiling() ? @"Stop Systrace" : @"Start Systrace";
|
NSString *profilingTitle = RCTProfileIsProfiling() ? @"Stop Systrace" : @"Start Systrace";
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:profilingTitle handler:^{
|
[items addObject:[RCTDevMenuItem buttonItemWithTitle:profilingTitle handler:^{
|
||||||
self.profilingEnabled = !_profilingEnabled;
|
weakSelf.profilingEnabled = !_profilingEnabled;
|
||||||
}]];
|
}]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +465,17 @@ RCT_EXPORT_METHOD(show)
|
||||||
|
|
||||||
NSArray *items = [self menuItems];
|
NSArray *items = [self menuItems];
|
||||||
for (RCTDevMenuItem *item in items) {
|
for (RCTDevMenuItem *item in items) {
|
||||||
|
switch (item.type) {
|
||||||
|
case RCTDevMenuTypeButton: {
|
||||||
[actionSheet addButtonWithTitle:item.title];
|
[actionSheet addButtonWithTitle:item.title];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RCTDevMenuTypeToggle: {
|
||||||
|
BOOL selected = [item.value boolValue];
|
||||||
|
[actionSheet addButtonWithTitle:selected? item.selectedTitle : item.title];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[actionSheet addButtonWithTitle:@"Cancel"];
|
[actionSheet addButtonWithTitle:@"Cancel"];
|
||||||
|
@ -357,7 +495,17 @@ RCT_EXPORT_METHOD(show)
|
||||||
}
|
}
|
||||||
|
|
||||||
RCTDevMenuItem *item = _presentedItems[buttonIndex];
|
RCTDevMenuItem *item = _presentedItems[buttonIndex];
|
||||||
item.handler();
|
switch (item.type) {
|
||||||
|
case RCTDevMenuTypeButton: {
|
||||||
|
[item callHandler];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RCTDevMenuTypeToggle: {
|
||||||
|
BOOL value = [_settings[item.key] boolValue];
|
||||||
|
[self updateSetting:item.key value:@(!value)]; // will call handler
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,18 +518,14 @@ RCT_EXPORT_METHOD(reload)
|
||||||
|
|
||||||
- (void)setShakeToShow:(BOOL)shakeToShow
|
- (void)setShakeToShow:(BOOL)shakeToShow
|
||||||
{
|
{
|
||||||
if (_shakeToShow != shakeToShow) {
|
|
||||||
_shakeToShow = shakeToShow;
|
_shakeToShow = shakeToShow;
|
||||||
[self updateSetting:@"shakeToShow" value: @(_shakeToShow)];
|
[self updateSetting:@"shakeToShow" value:@(_shakeToShow)];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setProfilingEnabled:(BOOL)enabled
|
- (void)setProfilingEnabled:(BOOL)enabled
|
||||||
{
|
{
|
||||||
if (_profilingEnabled != enabled) {
|
|
||||||
_profilingEnabled = enabled;
|
_profilingEnabled = enabled;
|
||||||
[self updateSetting:@"profilingEnabled" value: @(_profilingEnabled)];
|
[self updateSetting:@"profilingEnabled" value:@(_profilingEnabled)];
|
||||||
}
|
|
||||||
|
|
||||||
if (_liveReloadURL && enabled != RCTProfileIsProfiling()) {
|
if (_liveReloadURL && enabled != RCTProfileIsProfiling()) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
@ -394,10 +538,8 @@ RCT_EXPORT_METHOD(reload)
|
||||||
|
|
||||||
- (void)setLiveReloadEnabled:(BOOL)enabled
|
- (void)setLiveReloadEnabled:(BOOL)enabled
|
||||||
{
|
{
|
||||||
if (_liveReloadEnabled != enabled) {
|
|
||||||
_liveReloadEnabled = enabled;
|
_liveReloadEnabled = enabled;
|
||||||
[self updateSetting:@"liveReloadEnabled" value: @(_liveReloadEnabled)];
|
[self updateSetting:@"liveReloadEnabled" value:@(_liveReloadEnabled)];
|
||||||
}
|
|
||||||
|
|
||||||
if (_liveReloadEnabled) {
|
if (_liveReloadEnabled) {
|
||||||
[self checkForUpdates];
|
[self checkForUpdates];
|
||||||
|
@ -411,7 +553,7 @@ RCT_EXPORT_METHOD(reload)
|
||||||
{
|
{
|
||||||
if (_executorClass != executorClass) {
|
if (_executorClass != executorClass) {
|
||||||
_executorClass = executorClass;
|
_executorClass = executorClass;
|
||||||
[self updateSetting:@"executorClass" value: NSStringFromClass(executorClass)];
|
[self updateSetting:@"executorClass" value:NSStringFromClass(executorClass)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_bridge.executorClass != executorClass) {
|
if (_bridge.executorClass != executorClass) {
|
||||||
|
@ -433,17 +575,8 @@ RCT_EXPORT_METHOD(reload)
|
||||||
|
|
||||||
- (void)setShowFPS:(BOOL)showFPS
|
- (void)setShowFPS:(BOOL)showFPS
|
||||||
{
|
{
|
||||||
if (_showFPS != showFPS) {
|
|
||||||
_showFPS = showFPS;
|
_showFPS = showFPS;
|
||||||
|
|
||||||
if (showFPS) {
|
|
||||||
[_bridge.perfStats show];
|
|
||||||
} else {
|
|
||||||
[_bridge.perfStats hide];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self updateSetting:@"showFPS" value:@(showFPS)];
|
[self updateSetting:@"showFPS" value:@(showFPS)];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)checkForUpdates
|
- (void)checkForUpdates
|
||||||
|
@ -489,6 +622,7 @@ RCT_EXPORT_METHOD(reload)
|
||||||
- (void)show {}
|
- (void)show {}
|
||||||
- (void)reload {}
|
- (void)reload {}
|
||||||
- (void)addItem:(NSString *)title handler:(dispatch_block_t)handler {}
|
- (void)addItem:(NSString *)title handler:(dispatch_block_t)handler {}
|
||||||
|
- (void)addItem:(RCTDevMenu *)item {}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue