This commit is contained in:
ZaidElkurdi 2015-04-11 15:10:58 -07:00
parent c4f0c1f295
commit a38a11bb93
33 changed files with 396 additions and 118 deletions

View File

@ -1,6 +1,6 @@
include theos/makefiles/common.mk
export ARCHS = armv7s arm64
export ARCHS = armv7 armv7s arm64
export TARGET = iphone:clang:latest:8.0
export TARGET_IPHONEOS_DEPLOYMENT_VERSION = 8.0
export SDKVERSION=8.1

View File

@ -7,5 +7,5 @@ Maintainer: Zaid Elkurdi
Author: Zaid Elkurdi
Section: Tweaks
Icon: file:///Applications/AssistantPlusApp.app/Icon.png
Version: 1.0.0-2
Installed-Size: 1120
Version: 1.0.0-35
Installed-Size: 1364

View File

@ -11,7 +11,7 @@
@interface APActivatorListener : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *trigger;
@property (nonatomic, strong) NSArray *triggers;
@property (nonatomic) BOOL enabled;
@property (nonatomic) BOOL willPassthrough;
@property (nonatomic, strong) NSString *uniqueId;

View File

@ -13,7 +13,6 @@
- (id)initWithDictionary:(NSDictionary *)dict {
if (self = [super init]) {
NSString *name = dict[@"name"];
NSString *trigger = dict[@"trigger"];
NSString *identifier = dict[@"identifier"] ? dict[@"identifier"] : [NSString stringWithFormat:@"%@", [NSDate date]];
BOOL enabled = false;
@ -26,8 +25,17 @@
passthrough = [dict[@"passthrough"] boolValue];
}
//Migration from 1.0 - 1.01
id trigger = dict[@"trigger"];
if ([trigger isKindOfClass:[NSString class]]) {
self.triggers = @[trigger];
} else if ([trigger isKindOfClass:[NSArray class]]) {
self.triggers = trigger;
} else {
self.triggers = [NSArray array];
}
self.name = name;
self.trigger = trigger;
self.enabled = enabled;
self.willPassthrough = passthrough;
self.uniqueId = identifier;
@ -37,7 +45,7 @@
- (NSDictionary*)dictionaryRepresentation {
return @{@"name" : self.name ? self.name : @"Untitled",
@"trigger" : self.trigger ? self.trigger : @"",
@"trigger" : self.triggers ? self.triggers : [NSArray array],
@"enabled" : self.enabled ? [NSNumber numberWithBool:self.enabled] : [NSNumber numberWithBool:NO],
@"passthrough": self.willPassthrough ? [NSNumber numberWithBool:self.willPassthrough] : [NSNumber numberWithBool:NO],
@"identifier" : self.uniqueId };

View File

@ -93,8 +93,10 @@
[defaults synchronize];
}
#if !(TARGET_IPHONE_SIMULATOR)
CPDistributedMessagingCenter* center = [CPDistributedMessagingCenter centerNamed:@"com.zaid.applus.springboard"];
[center sendMessageName:@"UpdateActivatorListeners" userInfo:@{@"activatorListeners" : toSave}];
#endif
}
#pragma mark - Button Handlers
@ -117,8 +119,10 @@
}
- (void)respringPressed:(UIButton*)button {
#if !(TARGET_IPHONE_SIMULATOR)
CPDistributedMessagingCenter* center = [CPDistributedMessagingCenter centerNamed:@"com.zaid.applus.springboard"];
[center sendMessageName:@"respringForListeners" userInfo:nil];
#endif
}
#pragma mark - UITableViewDataSource
@ -132,7 +136,14 @@
APActivatorListener *currListener = [savedListeners objectAtIndex:indexPath.row];
cell.textLabel.text = currListener.name.length > 0 ? currListener.name : @"Untitled Listener";
cell.detailTextLabel.text = currListener.trigger.length > 0 ? currListener.trigger : @"No Trigger Yet";
NSMutableString *detailString = [NSMutableString string];
for (NSInteger currIndex = 0; currIndex < currListener.triggers.count; currIndex++) {
NSString *currTrigger = currListener.triggers[currIndex];
NSString *format = currIndex == currListener.triggers.count-1 ? @"%@" : @"%@, ";
[detailString appendString:[NSString stringWithFormat:format, currTrigger.length > 0 ? currTrigger : @"Empty Trigger"]];
}
cell.detailTextLabel.text = detailString.length > 0 ? detailString : @"No Trigger Yet";
return cell;
}

View File

@ -75,8 +75,10 @@
[defaults setObject:toSave forKey:@"customReplies"];
[defaults synchronize];
#if !(TARGET_IPHONE_SIMULATOR)
CPDistributedMessagingCenter* center = [CPDistributedMessagingCenter centerNamed:@"com.zaid.applus.springboard"];
[center sendMessageName:@"UpdateCustomReplies" userInfo:@{@"customReplies" : toSave}];
#endif
}
}

View File

@ -13,7 +13,7 @@
- (void)customReplyDidChange:(APCustomReply*)reply;
@end
@interface CustomReplyDetailViewController : UIViewController <UITextFieldDelegate, UITextViewDelegate>
@interface CustomReplyDetailViewController : UIViewController <UITextFieldDelegate, UITextViewDelegate, UITableViewDelegate, UITableViewDataSource>
- (id)initWithCustomReply:(APCustomReply*)reply;
@property (weak) id<CustomRepliesDelegate> delegate;
@end

View File

@ -10,8 +10,7 @@
@interface CustomReplyDetailViewController ()
@property (strong, nonatomic) APCustomReply *currReply;
@property (strong, nonatomic) UITextField *triggerField;
@property (strong, nonatomic) UITextView *responseField;
@property (strong, nonatomic) UITableView *tableView;
@property (nonatomic) BOOL didChange;
@end
@ -27,7 +26,6 @@
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidLoad {
@ -35,49 +33,132 @@
UIColor *backgroundColor = [UIColor colorWithWhite:.9f alpha:1.0];
self.view.backgroundColor = backgroundColor;
UIView *triggerBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 50)];
triggerBackground.backgroundColor = [UIColor whiteColor];
UILabel *triggerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 70, 50)];
triggerLabel.text = @"Trigger:";
self.triggerField = [[UITextField alloc] initWithFrame:CGRectMake(90, 2, self.view.frame.size.width-60, 50)];
self.triggerField.text = self.currReply.trigger;
self.triggerField.delegate = self;
[triggerBackground addSubview:triggerLabel];
[triggerBackground addSubview:self.triggerField];
[self.view addSubview:triggerBackground];
self.tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped];
self.tableView.delegate = self;
self.tableView.dataSource = self;
UIView *responseBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 190, self.view.frame.size.width, 100)];
responseBackground.backgroundColor = [UIColor whiteColor];
UILabel *responseLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 50)];
responseLabel.text = @"Response:";
self.responseField = [[UITextView alloc] initWithFrame:CGRectMake(110, 8, self.view.frame.size.width-110, 90)];
self.responseField.text = self.currReply.response;
self.responseField.font = [UIFont systemFontOfSize:16];
self.responseField.delegate = self;
[responseBackground addSubview:responseLabel];
[responseBackground addSubview:self.responseField];
[self.view addSubview:responseBackground];
CGFloat expectedHeight = [[self getHelpMessage] boundingRectWithSize:CGSizeMake(self.view.frame.size.width-20, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName : [UIFont fontWithName:@"Helvetica" size:14]}
context:nil].size.height;
UIView *msgView = [[UIView alloc] initWithFrame:CGRectMake(0, 10, self.view.frame.size.width, expectedHeight+30)];
UILabel *msgLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, self.view.frame.size.width-20, expectedHeight)];
msgLabel.lineBreakMode = NSLineBreakByWordWrapping;
msgLabel.numberOfLines = 0;
msgLabel.text = [self getHelpMessage];
msgLabel.textAlignment = NSTextAlignmentLeft;
msgLabel.font = [UIFont fontWithName:@"Helvetica" size:14];
msgLabel.textColor = [UIColor darkGrayColor];
[msgView addSubview:msgLabel];
self.tableView.tableFooterView = msgView;
[self.view addSubview:self.tableView];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(saveChangesIfNecessary)
name:UIApplicationWillResignActiveNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self saveChangesIfNecessary];
}
- (void)saveChangesIfNecessary {
if (self.didChange) {
self.currReply.trigger = self.triggerField.text;
self.currReply.response = self.responseField.text;
[self.delegate customReplyDidChange:self.currReply];
}
}
#pragma mark - UITableViewDataSource
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return [self createTriggerCell];
} else {
return [self createResponseCell];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return 50;
} else {
return 100;
}
}
#pragma mark - Cell Helpers
- (UITableViewCell*)createTriggerCell {
UITableViewCell *cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel *triggerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 70, 50)];
triggerLabel.text = @"Trigger:";
UITextField *triggerField = [[UITextField alloc] initWithFrame:CGRectMake(80, 9, self.view.frame.size.width-80, 35)];
triggerField.returnKeyType = UIReturnKeyDone;
triggerField.font = [UIFont systemFontOfSize:16];
triggerField.text = self.currReply.trigger;
triggerField.delegate = self;
[cell.contentView addSubview:triggerLabel];
[cell.contentView addSubview:triggerField];
return cell;
}
- (UITableViewCell*)createResponseCell {
UITableViewCell *cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 100)];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel *responseLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 50)];
responseLabel.text = @"Response:";
UITextView *responseField = [[UITextView alloc] initWithFrame:CGRectMake(95, 8, self.view.frame.size.width-100, 80)];
responseField.font = [UIFont systemFontOfSize:16];
responseField.text = self.currReply.response;
responseField.delegate = self;
[cell.contentView addSubview:responseLabel];
[cell.contentView addSubview:responseField];
return cell;
}
#pragma mark - UI Delegates
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
self.didChange = YES;
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
self.currReply.trigger = newString;
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
self.didChange = YES;
NSString *newString = [textView.text stringByReplacingCharactersInRange:range withString:text];
self.currReply.response = newString;
return YES;
}
#pragma mark - Helpers
- (NSString*)getHelpMessage {
return @"Trigger: The command that will trigger the custom reply. You may use wildcards in the trigger by using (.*). For example, '(.*)turn on the lights' will trigger on \"Turn on the lights\", \"Siri turn on the lights\", \"Hey Siri please turn on the lights\", etc.\n"
"\nResponse: What Siri will say in reponse to the trigger.\n";
}
@end

View File

@ -13,7 +13,7 @@
- (void)listenerDidChange:(APActivatorListener*)listener;
@end
@interface ListenerDetailViewController : UIViewController <UITextViewDelegate, UITextFieldDelegate>
@interface ListenerDetailViewController : UIViewController <UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate>
@property (assign) id<ListenerDetailDelegate> delegate;
- (id)initWithListener:(APActivatorListener*)listener;
@end

View File

@ -10,10 +10,9 @@
@interface ListenerDetailViewController ()
@property (strong, nonatomic) APActivatorListener *currListener;
@property (strong, nonatomic) UISwitch *enabledSwitch;
@property (strong, nonatomic) UISwitch *passthroughSwitch;
@property (strong, nonatomic) UITextField *nameField;
@property (strong, nonatomic) UITextView *triggerField;
@property (strong, nonatomic) UITableView *tableView;
@property (strong, nonatomic) NSMutableArray *mutableTriggers;
@property (nonatomic) BOOL didChange;
@end
@ -23,6 +22,8 @@
if (self = [super init]) {
self.currListener = listener;
self.didChange = NO;
self.mutableTriggers = listener.triggers.count > 0 ? [listener.triggers mutableCopy] : [NSMutableArray arrayWithObject:@""];
NSLog(@"Triggers: %@", self.mutableTriggers);
}
return self;
}
@ -32,57 +33,29 @@
UIColor *backgroundColor = [UIColor colorWithWhite:.9f alpha:1.0];
self.view.backgroundColor = backgroundColor;
UIView *switchBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 90, self.view.frame.size.width, 50)];
switchBackground.backgroundColor = [UIColor whiteColor];
self.tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped];
self.tableView.dataSource = self;
self.enabledSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(85, 9.5, 51, 31)];
[self.enabledSwitch addTarget:self action:@selector(didToggleSwitch:) forControlEvents:UIControlEventValueChanged];
self.enabledSwitch.on = self.currListener.enabled;
CGFloat expectedHeight = [[self getHelpMessage] boundingRectWithSize:CGSizeMake(self.view.frame.size.width-20, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName : [UIFont fontWithName:@"Helvetica" size:14]}
context:nil].size.height;
UIView *msgView = [[UIView alloc] initWithFrame:CGRectMake(0, 10, self.view.frame.size.width, expectedHeight+30)];
UILabel *msgLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, self.view.frame.size.width-20, expectedHeight)];
msgLabel.lineBreakMode = NSLineBreakByWordWrapping;
msgLabel.numberOfLines = 0;
msgLabel.text = [self getHelpMessage];
msgLabel.textAlignment = NSTextAlignmentLeft;
msgLabel.font = [UIFont fontWithName:@"Helvetica" size:14];
msgLabel.textColor = [UIColor darkGrayColor];
[msgView addSubview:msgLabel];
UILabel *enabledSwitchLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 80, 50)];
enabledSwitchLabel.text = @"Enabled:";
self.tableView.tableFooterView = msgView;
[self.view addSubview:self.tableView];
CGFloat viewWidth = self.view.frame.size.width;
self.passthroughSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(viewWidth-61, 9.5, 51, 31)];
[self.passthroughSwitch addTarget:self action:@selector(didToggleSwitch:) forControlEvents:UIControlEventValueChanged];
self.passthroughSwitch.on = self.currListener.willPassthrough;
CGFloat passthroughSwitchXOrigin = self.passthroughSwitch.frame.origin.x;
UILabel *passthroughSwitchLabel = [[UILabel alloc] initWithFrame:CGRectMake(passthroughSwitchXOrigin-110, 0, 110, 50)];
passthroughSwitchLabel.text = @"Passthrough:";
[switchBackground addSubview:enabledSwitchLabel];
[switchBackground addSubview:passthroughSwitchLabel];
[switchBackground addSubview:self.enabledSwitch];
[switchBackground addSubview:self.passthroughSwitch];
[self.view addSubview:switchBackground];
UIView *nameBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 170, self.view.frame.size.width, 50)];
nameBackground.backgroundColor = [UIColor whiteColor];
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 60, 50)];
nameLabel.text = @"Name:";
self.nameField = [[UITextField alloc] initWithFrame:CGRectMake(80, 2, self.view.frame.size.width-60, 50)];
self.nameField.text = self.currListener.name;
self.nameField.delegate = self;
[nameBackground addSubview:nameLabel];
[nameBackground addSubview:self.nameField];
[self.view addSubview:nameBackground];
UIView *triggerBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 230, self.view.frame.size.width, 100)];
triggerBackground.backgroundColor = [UIColor whiteColor];
UILabel *triggerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 70, 50)];
triggerLabel.text = @"Trigger:";
self.triggerField = [[UITextView alloc] initWithFrame:CGRectMake(80, 8, self.view.frame.size.width-80, 90)];
self.triggerField.font = [UIFont systemFontOfSize:16];
self.triggerField.text = self.currListener.trigger;
self.triggerField.delegate = self;
[triggerBackground addSubview:triggerLabel];
[triggerBackground addSubview:self.triggerField];
[self.view addSubview:triggerBackground];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewTrigger:)];
[self.navigationItem setRightBarButtonItem:addButton];
[[NSNotificationCenter defaultCenter]
addObserver:self
@ -98,30 +71,178 @@
- (void)saveChangesIfNecessary {
if (self.didChange) {
self.currListener.trigger = self.triggerField.text;
self.currListener.triggers = self.mutableTriggers;
self.currListener.name = self.nameField.text;
[self.delegate listenerDidChange:self.currListener];
}
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 1) {
if (self.mutableTriggers.count == 0) {
NSLog(@"Returing: 2!");
return 2;
} else {
NSLog(@"Returing: %ld", 1 + (long)self.mutableTriggers.count);
return 1 + self.mutableTriggers.count;
}
}
return 1;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return [self createSwitchCell];
}
if (indexPath.row == 0) {
return [self createNameCell];
} else {
return [self createTriggerCellForIndex:indexPath.row-1];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 50;
}
- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return @"";
}
#pragma mark - Cell Helpers
- (UITableViewCell*)createSwitchCell {
UITableViewCell *cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UISwitch *enabledSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(85, 9.5, 51, 31)];
[enabledSwitch addTarget:self action:@selector(didToggleSwitch:) forControlEvents:UIControlEventValueChanged];
enabledSwitch.tag = 117;
enabledSwitch.on = self.currListener.enabled;
UILabel *enabledSwitchLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 80, 50)];
enabledSwitchLabel.text = @"Enabled:";
CGFloat viewWidth = self.view.frame.size.width;
UISwitch *passthroughSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(viewWidth-61, 9.5, 51, 31)];
[passthroughSwitch addTarget:self action:@selector(didToggleSwitch:) forControlEvents:UIControlEventValueChanged];
passthroughSwitch.on = self.currListener.willPassthrough;
CGFloat passthroughSwitchXOrigin = passthroughSwitch.frame.origin.x;
UILabel *passthroughSwitchLabel = [[UILabel alloc] initWithFrame:CGRectMake(passthroughSwitchXOrigin-110, 0, 110, 50)];
passthroughSwitchLabel.text = @"Passthrough:";
[cell.contentView addSubview:enabledSwitchLabel];
[cell.contentView addSubview:passthroughSwitchLabel];
[cell.contentView addSubview:enabledSwitch];
[cell.contentView addSubview:passthroughSwitch];
return cell;
}
- (UITableViewCell*)createNameCell {
UITableViewCell *cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 60, 50)];
nameLabel.text = @"Name:";
UITextField *nameField = [[UITextField alloc] initWithFrame:CGRectMake(80, 2, self.view.frame.size.width-60, 50)];
nameField.text = self.currListener.name;
nameField.delegate = self;
nameField.tag = -1;
nameField.returnKeyType = UIReturnKeyDone;
self.nameField = nameField;
[cell.contentView addSubview:nameLabel];
[cell.contentView addSubview:nameField];
return cell;
}
- (UITableViewCell*)createTriggerCellForIndex:(NSInteger)index {
NSLog(@"Getting cell for index: %ld", (long)index);
UITableViewCell *cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *triggerBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 230, self.view.frame.size.width, 100)];
triggerBackground.backgroundColor = [UIColor whiteColor];
UILabel *triggerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 70, 50)];
triggerLabel.text = @"Trigger:";
UITextField *triggerField = [[UITextField alloc] initWithFrame:CGRectMake(80, 8, self.view.frame.size.width-80, 35)];
triggerField.returnKeyType = UIReturnKeyDone;
triggerField.font = [UIFont systemFontOfSize:16];
if (index < self.currListener.triggers.count) {
triggerField.text = self.currListener.triggers[index];
}
triggerField.delegate = self;
triggerField.tag = index;
[cell.contentView addSubview:triggerLabel];
[cell.contentView addSubview:triggerField];
return cell;
}
#pragma mark - UITableViewDelegate
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1 && (indexPath.row == 0 || indexPath.row == 1)) {
return NO;
}
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.mutableTriggers removeObjectAtIndex:indexPath.row-1];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
self.didChange = YES;
}
}
#pragma mark - UI Delegates
- (void)addNewTrigger:(id)sender {
[self.mutableTriggers addObject:@""];
NSLog(@"Mutable triggers: %@", self.mutableTriggers);
NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:self.mutableTriggers.count inSection:1];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
- (void)didToggleSwitch:(UISwitch*)theSwitch {
self.didChange = YES;
if (theSwitch == self.enabledSwitch) {
if (theSwitch.tag == 117) {
self.currListener.enabled = theSwitch.on;
} else if (theSwitch == self.passthroughSwitch) {
} else {
self.currListener.willPassthrough = theSwitch.on;
}
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
self.didChange = YES;
return YES;
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
self.didChange = YES;
if (textField.tag >= 0) {
[self.mutableTriggers setObject:[textField.text stringByReplacingCharactersInRange:range withString:string] atIndexedSubscript:textField.tag];
}
return YES;
}
@ -129,4 +250,14 @@
[super didReceiveMemoryWarning];
}
#pragma mark - Helpers
- (NSString*)getHelpMessage {
return @"Enabled: For a listener to appear in Activator it must be enabled\n"
"\nPassthrough: If enabled, Assistant+ will continue searching for another Activator listener, custom reply, or plugin to handle the command. If it doesn't find anything to handle the command, Siri will go to its default action. You can add a voice confirmation for your Activator listener if you create a custom reply for the same trigger and then enable passthrough for your listener\n"
"\nName: A name to describe your listener. This can be anything and is purely for informational purposes\n"
"\nTrigger: The command that will trigger the Activator listener, you must have at least one for the listener to appear in Activator. You may use wildcards in the trigger by using (.*). For example, '(.*)turn on the lights' will trigger on \"Turn on the lights\", \"Siri turn on the lights\", \"Hey Siri please turn on the lights\", etc.\n"
"\nOnce you create an Activator listener here you must go to Activator and assign it to an event.";
}
@end

View File

@ -98,9 +98,11 @@
[self goToNewVC:[[CustomRepliesViewController alloc] init]];
break;
case 2: {
#if !(TARGET_IPHONE_SIMULATOR)
CPDistributedMessagingCenter *center = [CPDistributedMessagingCenter centerNamed:@"com.zaid.applus.springboard"];
NSDictionary *installed = [center sendMessageAndReceiveReplyName:@"getInstalledPlugins" userInfo:nil];
[self goToNewVC:[[PluginsViewController alloc] initWithInstalledPlugins:installed[@"plugins"]]];
#endif
break; }
default:
break;

View File

@ -10,8 +10,8 @@
@interface APActivatorListener : NSObject
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *triggerString;
@property (strong, nonatomic) NSRegularExpression *trigger;
@property (strong, nonatomic) NSArray *triggerStrings;
@property (strong, nonatomic) NSArray *triggers;
@property (strong, nonatomic) NSString *identifier;
@property (nonatomic) BOOL willPassthrough;
- (id)initWithDictionary:(NSDictionary*)dict;

View File

@ -13,8 +13,29 @@
- (id)initWithDictionary:(NSDictionary*)dict {
if (self = [super init]) {
self.name = dict[@"name"];
self.triggerString = dict[@"trigger"];
self.trigger = [NSRegularExpression regularExpressionWithPattern:self.triggerString options:NSRegularExpressionCaseInsensitive error:nil];
//Migration 1.0 -> 1.01
id triggerFromDict = dict[@"trigger"];
if ([triggerFromDict isKindOfClass:[NSString class]]) {
self.triggerStrings = @[triggerFromDict];
} else if ([triggerFromDict isKindOfClass:[NSArray class]]) {
self.triggerStrings = triggerFromDict;
} else {
self.triggerStrings = [NSArray array];
}
NSMutableArray *regexTriggers = [[NSMutableArray alloc] init];
for (NSString *currTrigger in self.triggerStrings) {
if (currTrigger.length > 0) {
NSRegularExpression *newRegex = [NSRegularExpression regularExpressionWithPattern:currTrigger options:NSRegularExpressionCaseInsensitive error:nil];
if (newRegex) {
[regexTriggers addObject:newRegex];
}
}
}
self.triggers = regexTriggers;
self.identifier = dict[@"identifier"];
NSNumber *pass = dict[@"passthrough"];

View File

@ -61,14 +61,16 @@ static NSString *EVENT_PREFIX = @"APListener";
NSString *userCommand = [command lowercaseString];
userCommand = [userCommand stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
for (APActivatorListener *currListener in activatorListenersArray) {
NSArray *arrayOfAllMatches = [currListener.trigger matchesInString:userCommand options:0 range:NSMakeRange(0, [userCommand length])];
for (NSTextCheckingResult *match in arrayOfAllMatches) {
if (match.numberOfRanges > 0) {
NSString *eventName = [NSString stringWithFormat:@"%@%@", EVENT_PREFIX, currListener.identifier];
[LASharedActivator sendEventToListener:[LAEvent eventWithName:eventName mode:LASharedActivator.currentEventMode]];
if (!currListener.willPassthrough) {
[currSession sendRequestCompleted];
return YES;
for (NSRegularExpression *currExpression in currListener.triggers) {
NSArray *arrayOfAllMatches = [currExpression matchesInString:userCommand options:0 range:NSMakeRange(0, [userCommand length])];
for (NSTextCheckingResult *match in arrayOfAllMatches) {
if (match.numberOfRanges > 0) {
NSString *eventName = [NSString stringWithFormat:@"%@%@", EVENT_PREFIX, currListener.identifier];
[LASharedActivator sendEventToListener:[LAEvent eventWithName:eventName mode:LASharedActivator.currentEventMode]];
if (!currListener.willPassthrough) {
[currSession sendRequestCompleted];
return YES;
}
}
}
}
@ -122,16 +124,29 @@ static NSString *EVENT_PREFIX = @"APListener";
if ([listeners objectForKey:@"activatorListeners"]) {
for (NSDictionary *currListener in [listeners objectForKey:@"activatorListeners"]) {
NSString *trigger = currListener[@"trigger"];
BOOL isEnabled = [currListener[@"enabled"] boolValue];
if (trigger.length > 0 && isEnabled) {
APActivatorListener *newListener = [[APActivatorListener alloc] initWithDictionary:currListener];
NSString *eventName = [NSString stringWithFormat:@"%@%@", EVENT_PREFIX, newListener.identifier];
[activatorListenersArray addObject:newListener];
[LASharedActivator registerEventDataSource:self forEventName:eventName];
BOOL isValid = NO;
id triggerValue = currListener[@"trigger"];
if ([triggerValue isKindOfClass:[NSArray class]]) {
NSArray *triggers = (NSArray*)triggerValue;
isValid = triggers.count > 0 && isEnabled;
if (isValid) {
NSString *firstTrigger = triggers[0];
isValid = firstTrigger.length > 0;
}
} else {
//Migration 1.0 -> 1.01
NSString *trigger = (NSString*)triggerValue;
isValid = trigger.length > 0 && isEnabled;
}
if (isValid) {
APActivatorListener *newListener = [[APActivatorListener alloc] initWithDictionary:currListener];
NSString *eventName = [NSString stringWithFormat:@"%@%@", EVENT_PREFIX, newListener.identifier];
[activatorListenersArray addObject:newListener];
[LASharedActivator registerEventDataSource:self forEventName:eventName];
}
}
}
}
}
- (NSString *)localizedTitleForEventName:(NSString *)eventName {
@ -152,8 +167,15 @@ static NSString *EVENT_PREFIX = @"APListener";
- (NSString *)localizedDescriptionForEventName:(NSString *)eventName {
for (APActivatorListener *currListener in activatorListenersArray) {
NSString *comp = [NSString stringWithFormat:@"%@%@", EVENT_PREFIX, currListener.identifier];
if ([comp isEqualToString:eventName]) {
return [NSString stringWithFormat:@"Siri Query - \"%@\"", currListener.triggerString];
NSMutableString *descriptionString = [NSMutableString string];
for (NSInteger currIndex = 0; currIndex < currListener.triggerStrings.count; currIndex++) {
NSString *currTrigger = currListener.triggerStrings[currIndex];
NSString *format = currIndex == currListener.triggerStrings.count-1 ? @"\"%@\"" : @"\"%@\", ";
[descriptionString appendString:[NSString stringWithFormat:format, currTrigger.length > 0 ? currTrigger : @"Empty Trigger"]];
}
return [NSString stringWithFormat:@"Siri Query - %@", descriptionString];
}
}

Binary file not shown.

View File

@ -1,10 +1,10 @@
Package: com.assistantplus.spotifycontrols
Name: spotifySiriControls
Depends: mobilesubstrate, com.zaid.assistant+
Depends: mobilesubstrate
Architecture: iphoneos-arm
Description: Control Spotify using Siri! Currently spotifySiriControls supports searching for tracks, artists, and albums using commands like, “Search for Drake on Spotify”, “Search Taylor Swift on Spotify”, “Play Books by Swiss Lips on Spotify”, and “Play Paris on Spotify”.
Maintainer: Zaid Elkurdi
Author: Zaid Elkurdi
Section: Tweaks
Version: 1.0.0-6
Version: 1.0.0-13
Installed-Size: 616

View File

@ -1,6 +1,6 @@
Package: com.assistantplus.spotifycontrols
Name: spotifySiriControls
Depends: mobilesubstrate, com.zaid.assistant+
Depends: mobilesubstrate
Version: 1.0.0
Architecture: iphoneos-arm
Description: Control Spotify using Siri! Currently spotifySiriControls supports searching for tracks, artists, and albums using commands like, “Search for Drake on Spotify”, “Search Taylor Swift on Spotify”, “Play Books by Swiss Lips on Spotify”, and “Play Paris on Spotify”.