Commit fc41c7d0 by Sebastián Katzer

Internal changes related with action groups

parent ca137432
...@@ -72,6 +72,9 @@ ...@@ -72,6 +72,9 @@
<header-file src="src/ios/APPLocalNotification.h" /> <header-file src="src/ios/APPLocalNotification.h" />
<source-file src="src/ios/APPLocalNotification.m" /> <source-file src="src/ios/APPLocalNotification.m" />
<header-file src="src/ios/APPNotificationCategory.h" />
<source-file src="src/ios/APPNotificationCategory.m" />
<header-file src="src/ios/APPNotificationContent.h" /> <header-file src="src/ios/APPNotificationContent.h" />
<source-file src="src/ios/APPNotificationContent.m" /> <source-file src="src/ios/APPNotificationContent.m" />
......
...@@ -232,12 +232,13 @@ public class LocalNotification extends CordovaPlugin { ...@@ -232,12 +232,13 @@ public class LocalNotification extends CordovaPlugin {
private void actions (JSONArray args, CallbackContext command) { private void actions (JSONArray args, CallbackContext command) {
int task = args.optInt(0); int task = args.optInt(0);
String id = args.optString(1); String id = args.optString(1);
JSONObject spec = args.optJSONObject(2); JSONArray list = args.optJSONArray(2);
Context context = cordova.getActivity();
switch (task) { switch (task) {
case 0: case 0:
ActionGroup group = ActionGroup.parse(cordova.getActivity(), spec); ActionGroup group = ActionGroup.parse(context, id, list);
if (group != null) ActionGroup.register(group); ActionGroup.register(group);
command.success(); command.success();
break; break;
case 1: case 1:
......
...@@ -612,7 +612,7 @@ public final class Options { ...@@ -612,7 +612,7 @@ public final class Options {
group = ActionGroup.lookup(groupId); group = ActionGroup.lookup(groupId);
} else } else
if (actions != null && actions.length() > 0) { if (actions != null && actions.length() > 0) {
group = ActionGroup.parse(context, options); group = ActionGroup.parse(context, actions);
} }
return (group != null) ? group.getActions() : null; return (group != null) ? group.getActions() : null;
......
...@@ -37,12 +37,8 @@ import static android.os.Build.VERSION_CODES.N; ...@@ -37,12 +37,8 @@ import static android.os.Build.VERSION_CODES.N;
public final class ActionGroup { public final class ActionGroup {
// Default action group id
private static final String GENERAL_ACTION_GROUP = "DEFAULT_GROUP";
// Saves all groups for later lookup. // Saves all groups for later lookup.
private static final Map<String, ActionGroup> groups = private static final Map<String, ActionGroup> groups = new HashMap<String, ActionGroup>();
new HashMap<String, ActionGroup>();
// The ID of the action group. // The ID of the action group.
private final String id; private final String id;
...@@ -67,9 +63,7 @@ public final class ActionGroup { ...@@ -67,9 +63,7 @@ public final class ActionGroup {
* @param group The action group to register. * @param group The action group to register.
*/ */
public static void register (ActionGroup group) { public static void register (ActionGroup group) {
if (!group.getId().equalsIgnoreCase(GENERAL_ACTION_GROUP)) { groups.put(group.getId(), group);
groups.put(group.getId(), group);
}
} }
/** /**
...@@ -93,17 +87,23 @@ public final class ActionGroup { ...@@ -93,17 +87,23 @@ public final class ActionGroup {
/** /**
* Creates an action group by parsing the specified action specs. * Creates an action group by parsing the specified action specs.
* *
* @param spec The action group spec containing the id and list of actions. * @param list The list of actions.
* *
* @return A new action group. * @return A new action group.
*/ */
public static ActionGroup parse (Context context, JSONObject spec) { public static ActionGroup parse (Context context, JSONArray list) {
String id = spec.optString("actionGroupId", GENERAL_ACTION_GROUP); return parse(context, null, list);
JSONArray list = spec.optJSONArray("actions"); }
if (list == null || list.length() == 0)
return null;
/**
* Creates an action group by parsing the specified action specs.
*
* @param id The id for the action group.
* @param list The list of actions.
*
* @return A new action group.
*/
public static ActionGroup parse (Context context, String id, JSONArray list) {
List<Action> actions = new ArrayList<Action>(list.length()); List<Action> actions = new ArrayList<Action>(list.length());
for (int i = 0; i < list.length(); i++) { for (int i = 0; i < list.length(); i++) {
...@@ -123,9 +123,6 @@ public final class ActionGroup { ...@@ -123,9 +123,6 @@ public final class ActionGroup {
actions.add(new Action(context, opts)); actions.add(new Action(context, opts));
} }
if (actions.isEmpty())
return null;
return new ActionGroup(id, actions.toArray(new Action[actions.size()])); return new ActionGroup(id, actions.toArray(new Action[actions.size()]));
} }
......
...@@ -20,10 +20,11 @@ ...@@ -20,10 +20,11 @@
*/ */
#import "APPLocalNotification.h" #import "APPLocalNotification.h"
#import "APPNotificationContent.h"
#import "APPNotificationOptions.h" #import "APPNotificationOptions.h"
#import "APPNotificationCategory.h"
#import "UNUserNotificationCenter+APPLocalNotification.h" #import "UNUserNotificationCenter+APPLocalNotification.h"
#import "UNNotificationRequest+APPLocalNotification.h" #import "UNNotificationRequest+APPLocalNotification.h"
#import "APPNotificationContent.h"
@interface APPLocalNotification () @interface APPLocalNotification ()
...@@ -398,18 +399,16 @@ UNNotificationPresentationOptions const OptionAlert = UNNotificationPresentation ...@@ -398,18 +399,16 @@ UNNotificationPresentationOptions const OptionAlert = UNNotificationPresentation
- (void) actions:(CDVInvokedUrlCommand *)command - (void) actions:(CDVInvokedUrlCommand *)command
{ {
[self.commandDelegate runInBackground:^{ [self.commandDelegate runInBackground:^{
int code = [command.arguments[0] intValue]; int code = [command.arguments[0] intValue];
NSString* identifier = [command argumentAtIndex:1]; NSString* identifier = [command argumentAtIndex:1];
NSDictionary* options = [command argumentAtIndex:2]; NSArray* actions = [command argumentAtIndex:2];
APPNotificationContent* notification; UNNotificationCategory* group;
BOOL found; BOOL found;
switch (code) { switch (code) {
case 0: case 0:
notification = [[APPNotificationContent alloc] group = [APPNotificationCategory parse:actions withId:identifier];
initWithOptions:options]; [_center addActionGroup:group];
[_center addActionGroup:notification.category];
[self execCallback:command]; [self execCallback:command];
break; break;
case 1: case 1:
......
/*
* Apache 2.0 License
*
* Copyright (c) Sebastian Katzer 2017
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
@import UserNotifications;
@interface APPNotificationCategory : NSObject
+ (UNNotificationCategory*) parse:(NSArray*)list withId:(NSString*)groupId;
@end
/*
* Apache 2.0 License
*
* Copyright (c) Sebastian Katzer 2017
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
#import "APPNotificationCategory.h"
@import UserNotifications;
@implementation APPNotificationCategory : NSObject
#pragma mark -
#pragma mark Public
/**
* Parse the provided spec map into an action group.
*
* @param [ NSDictionary* ] spec A key-value property map.
* Must contain an id and a list of actions.
*
* @return [ UNNotificationCategory* ]
*/
+ (UNNotificationCategory*) parse:(NSArray*)list withId:(NSString*)groupId
{
NSArray* actions = [self parseActions:list];
return [UNNotificationCategory categoryWithIdentifier:groupId
actions:actions
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
}
#pragma mark -
#pragma mark Private
/**
* The actions of the action group.
*
* @return [ NSArray* ]
*/
+ (NSArray<UNNotificationAction *> *) parseActions:(NSArray*)items
{
NSMutableArray* actions = [[NSMutableArray alloc] init];
for (NSDictionary* item in items) {
NSString* id = item[@"id"];
NSString* title = item[@"title"];
NSString* type = item[@"type"];
UNNotificationActionOptions options = UNNotificationActionOptionNone;
UNNotificationAction* action;
if ([item[@"launch"] boolValue]) {
options = UNNotificationActionOptionForeground;
}
if ([item[@"ui"] isEqualToString:@"decline"]) {
options = options | UNNotificationActionOptionDestructive;
}
if ([item[@"needsAuth"] boolValue]) {
options = options | UNNotificationActionOptionAuthenticationRequired;
}
if ([type isEqualToString:@"input"]) {
NSString* submitTitle = item[@"submitTitle"];
NSString* placeholder = item[@"emptyText"];
if (!submitTitle.length) {
submitTitle = @"Submit";
}
action = [UNTextInputNotificationAction actionWithIdentifier:id
title:title
options:options
textInputButtonTitle:submitTitle
textInputPlaceholder:placeholder];
} else
if (!type.length || [type isEqualToString:@"button"]) {
action = [UNNotificationAction actionWithIdentifier:id
title:title
options:options];
} else {
NSLog(@"Unknown action type: %@", type);
}
if (action) {
[actions addObject:action];
}
}
return actions;
}
@end
...@@ -28,6 +28,5 @@ ...@@ -28,6 +28,5 @@
- (id) initWithOptions:(NSDictionary*)dict; - (id) initWithOptions:(NSDictionary*)dict;
- (APPNotificationOptions*) options; - (APPNotificationOptions*) options;
- (UNNotificationRequest*) request; - (UNNotificationRequest*) request;
- (UNNotificationCategory*) category;
@end @end
...@@ -104,25 +104,6 @@ static char optionsKey; ...@@ -104,25 +104,6 @@ static char optionsKey;
trigger:opts.trigger]; trigger:opts.trigger];
} }
/**
* The category for the notification with all the actions.
*
* @return [ UNNotificationCategory* ]
*/
- (UNNotificationCategory*) category
{
NSString* categoryId = self.categoryIdentifier;
NSArray* actions = self.options.actions;
if (!actions.count)
return NULL;
return [UNNotificationCategory categoryWithIdentifier:categoryId
actions:actions
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
}
#pragma mark - #pragma mark -
#pragma mark Private #pragma mark Private
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
@property (readonly, getter=priority) int priority; @property (readonly, getter=priority) int priority;
@property (readonly, getter=sound) UNNotificationSound* sound; @property (readonly, getter=sound) UNNotificationSound* sound;
@property (readonly, getter=userInfo) NSDictionary* userInfo; @property (readonly, getter=userInfo) NSDictionary* userInfo;
@property (readonly, getter=actions) NSArray<UNNotificationAction*>*actions;
@property (readonly, getter=attachments) NSArray<UNNotificationAttachment*>*attachments; @property (readonly, getter=attachments) NSArray<UNNotificationAttachment*>*attachments;
- (id) initWithDict:(NSDictionary*) dict; - (id) initWithDict:(NSDictionary*) dict;
......
...@@ -67,7 +67,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -67,7 +67,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (NSNumber*) id - (NSNumber*) id
{ {
NSInteger id = [[dict objectForKey:@"id"] integerValue]; NSInteger id = [dict[@"id"] integerValue];
return [NSNumber numberWithInteger:id]; return [NSNumber numberWithInteger:id];
} }
...@@ -89,7 +89,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -89,7 +89,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (NSString*) title - (NSString*) title
{ {
return [dict objectForKey:@"title"]; return dict[@"title"];
} }
/** /**
...@@ -111,7 +111,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -111,7 +111,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (NSString*) text - (NSString*) text
{ {
return [dict objectForKey:@"text"]; return dict[@"text"];
} }
/** /**
...@@ -121,7 +121,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -121,7 +121,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (BOOL) silent - (BOOL) silent
{ {
return [[dict objectForKey:@"silent"] boolValue]; return [dict[@"silent"] boolValue];
} }
/** /**
...@@ -131,7 +131,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -131,7 +131,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (int) priority - (int) priority
{ {
return [[dict objectForKey:@"priority"] intValue]; return [dict[@"priority"] intValue];
} }
/** /**
...@@ -141,7 +141,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -141,7 +141,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (NSNumber*) badge - (NSNumber*) badge
{ {
id value = [dict objectForKey:@"badge"]; id value = dict[@"badge"];
return (value == NULL) ? NULL : [NSNumber numberWithInt:[value intValue]]; return (value == NULL) ? NULL : [NSNumber numberWithInt:[value intValue]];
} }
...@@ -153,14 +153,9 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -153,14 +153,9 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (NSString*) actionGroupId - (NSString*) actionGroupId
{ {
id actions = [dict objectForKey:@"actions"]; id actions = dict[@"actions"];
if ([actions isKindOfClass:NSString.class]) return ([actions isKindOfClass:NSString.class]) ? actions : kAPPGeneralCategory;
return actions;
NSString* value = [dict objectForKey:@"actionGroupId"];
return value.length ? value : kAPPGeneralCategory;
} }
/** /**
...@@ -170,7 +165,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -170,7 +165,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (UNNotificationSound*) sound - (UNNotificationSound*) sound
{ {
NSString* path = [dict objectForKey:@"sound"]; NSString* path = dict[@"sound"];
NSString* file; NSString* file;
if ([path isKindOfClass:NSNumber.class]) { if ([path isKindOfClass:NSNumber.class]) {
...@@ -198,7 +193,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -198,7 +193,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (NSArray<UNNotificationAttachment *> *) attachments - (NSArray<UNNotificationAttachment *> *) attachments
{ {
NSArray* paths = [dict objectForKey:@"attachments"]; NSArray* paths = dict[@"attachments"];
NSMutableArray* attachments = [[NSMutableArray alloc] init]; NSMutableArray* attachments = [[NSMutableArray alloc] init];
if (!paths) if (!paths)
...@@ -221,69 +216,6 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -221,69 +216,6 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
return attachments; return attachments;
} }
/**
* Additional actions for the notification.
*
* @return [ NSArray* ]
*/
- (NSArray<UNNotificationAction *> *) actions
{
NSArray* items = [dict objectForKey:@"actions"];
NSMutableArray* actions = [[NSMutableArray alloc] init];
if (!items)
return actions;
for (NSDictionary* item in items) {
NSString* id = [item objectForKey:@"id"];
NSString* title = [item objectForKey:@"title"];
NSString* type = [item objectForKey:@"type"];
UNNotificationActionOptions options = UNNotificationActionOptionNone;
UNNotificationAction* action;
if ([[item objectForKey:@"launch"] boolValue]) {
options = UNNotificationActionOptionForeground;
}
if ([[item objectForKey:@"ui"] isEqualToString:@"decline"]) {
options = options | UNNotificationActionOptionDestructive;
}
if ([[item objectForKey:@"needsAuth"] boolValue]) {
options = options | UNNotificationActionOptionAuthenticationRequired;
}
if ([type isEqualToString:@"input"]) {
NSString* submitTitle = [item objectForKey:@"submitTitle"];
NSString* placeholder = [item objectForKey:@"emptyText"];
if (!submitTitle.length) {
submitTitle = @"Submit";
}
action = [UNTextInputNotificationAction actionWithIdentifier:id
title:title
options:options
textInputButtonTitle:submitTitle
textInputPlaceholder:placeholder];
} else
if (!type.length || [type isEqualToString:@"button"]) {
action = [UNNotificationAction actionWithIdentifier:id
title:title
options:options];
} else {
NSLog(@"Unknown action type: %@", type);
}
if (action) {
[actions addObject:action];
}
}
return actions;
}
#pragma mark - #pragma mark -
#pragma mark Public #pragma mark Public
...@@ -315,7 +247,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -315,7 +247,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
*/ */
- (NSDictionary*) userInfo - (NSDictionary*) userInfo
{ {
if ([dict objectForKey:@"updatedAt"]) { if (dict[@"updatedAt"]) {
NSMutableDictionary* data = [dict mutableCopy]; NSMutableDictionary* data = [dict mutableCopy];
[data removeObjectForKey:@"updatedAt"]; [data removeObjectForKey:@"updatedAt"];
...@@ -331,7 +263,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 }; ...@@ -331,7 +263,7 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
- (id) valueForTriggerOption:(NSString*)key - (id) valueForTriggerOption:(NSString*)key
{ {
return [[dict objectForKey:@"trigger"] objectForKey:key]; return dict[@"trigger"][key];
} }
/** /**
......
...@@ -271,12 +271,12 @@ exports.actions = function (success, error, args) { ...@@ -271,12 +271,12 @@ exports.actions = function (success, error, args) {
code = args[0], code = args[0],
id = args[1], id = args[1],
res = [], res = [],
opts, group; list, group;
switch (code) { switch (code) {
case 0: case 0:
opts = exports.parseOptions(args[2]); list = exports.parseActions({ actions:args[2] });
group = new ActionGroup(id, opts.actions); group = new ActionGroup(id, list);
ActionGroup.register(group); ActionGroup.register(group);
break; break;
......
...@@ -393,8 +393,7 @@ exports.getTriggered = function (callback, scope) { ...@@ -393,8 +393,7 @@ exports.getTriggered = function (callback, scope) {
* @return [ Void ] * @return [ Void ]
*/ */
exports.addActions = function (id, actions, callback, scope) { exports.addActions = function (id, actions, callback, scope) {
var config = { actionGroupId: id, actions: actions }; this._exec('actions', [0, id, actions], callback, scope);
this._exec('actions', [0, id, config], callback, scope);
}; };
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment