108 lines
3.1 KiB
Mathematica
108 lines
3.1 KiB
Mathematica
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||
|
|
||
|
#import "RCTAlertManager.h"
|
||
|
|
||
|
#import "RCTLog.h"
|
||
|
|
||
|
@interface RCTAlertManager() <UIAlertViewDelegate>
|
||
|
|
||
|
@end
|
||
|
|
||
|
@implementation RCTAlertManager
|
||
|
{
|
||
|
NSMutableArray *_alerts;
|
||
|
NSMutableArray *_alertCallbacks;
|
||
|
NSMutableArray *_alertButtonKeys;
|
||
|
}
|
||
|
|
||
|
- (instancetype)init
|
||
|
{
|
||
|
if ((self = [super init])) {
|
||
|
_alerts = [[NSMutableArray alloc] init];
|
||
|
_alertCallbacks = [[NSMutableArray alloc] init];
|
||
|
_alertButtonKeys = [[NSMutableArray alloc] init];
|
||
|
}
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {NSDictionary} args Dictionary of the form
|
||
|
*
|
||
|
* @{
|
||
|
* @"message": @"<Alert message>",
|
||
|
* @"buttons": @[
|
||
|
* @{@"<key1>": @"<title1>"},
|
||
|
* @{@"<key2>": @"<cancelButtonTitle>"},
|
||
|
* ]
|
||
|
* }
|
||
|
* The key from the `buttons` dictionary is passed back in the callback on click.
|
||
|
* Buttons are displayed in the order they are specified. If "cancel" is used as
|
||
|
* the button key, it will be differently highlighted, according to iOS UI conventions.
|
||
|
*/
|
||
|
- (void)alertWithArgs:(NSDictionary *)args callback:(RCTResponseSenderBlock)callback
|
||
|
{
|
||
|
RCT_EXPORT();
|
||
|
|
||
|
NSString *title = args[@"title"];
|
||
|
NSString *message = args[@"message"];
|
||
|
NSArray *buttons = args[@"buttons"];
|
||
|
|
||
|
if (!title && !message) {
|
||
|
RCTLogMustFix(@"Must specify either an alert title, or message, or both");
|
||
|
return;
|
||
|
} else if (buttons.count == 0) {
|
||
|
RCTLogMustFix(@"Must have at least one button.");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||
|
|
||
|
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
|
||
|
message:message
|
||
|
delegate:self
|
||
|
cancelButtonTitle:nil
|
||
|
otherButtonTitles:nil];
|
||
|
|
||
|
NSMutableArray *buttonKeys = [[NSMutableArray alloc] initWithCapacity:buttons.count];
|
||
|
|
||
|
NSInteger index = 0;
|
||
|
for (NSDictionary *button in buttons) {
|
||
|
if (button.count != 1) {
|
||
|
RCTLogMustFix(@"Button definitions should have exactly one key.");
|
||
|
}
|
||
|
NSString *buttonKey = [button.allKeys firstObject];
|
||
|
NSString *buttonTitle = [button[buttonKey] description];
|
||
|
[alertView addButtonWithTitle:buttonTitle];
|
||
|
if ([buttonKey isEqualToString: @"cancel"]) {
|
||
|
alertView.cancelButtonIndex = index;
|
||
|
}
|
||
|
[buttonKeys addObject:buttonKey];
|
||
|
index ++;
|
||
|
}
|
||
|
|
||
|
[_alerts addObject:alertView];
|
||
|
[_alertCallbacks addObject:callback ?: ^(id unused) {}];
|
||
|
[_alertButtonKeys addObject:buttonKeys];
|
||
|
|
||
|
[alertView show];
|
||
|
});
|
||
|
}
|
||
|
|
||
|
#pragma mark - UIAlertViewDelegate
|
||
|
|
||
|
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||
|
{
|
||
|
NSUInteger index = [_alerts indexOfObject:alertView];
|
||
|
RCTAssert(index != NSNotFound, @"Dismissed alert was not recognised");
|
||
|
|
||
|
RCTResponseSenderBlock callback = _alertCallbacks[index];
|
||
|
NSArray *buttonKeys = _alertButtonKeys[index];
|
||
|
callback(@[buttonKeys[buttonIndex]]);
|
||
|
|
||
|
[_alerts removeObjectAtIndex:index];
|
||
|
[_alertCallbacks removeObjectAtIndex:index];
|
||
|
[_alertButtonKeys removeObjectAtIndex:index];
|
||
|
}
|
||
|
|
||
|
@end
|