Просмотр исходного кода

Disable support for implicit action group decleration

Sebastián Katzer 7 лет назад
Родитель
Сommit
5759483e16

+ 52 - 15
src/android/LocalNotification.java

@@ -131,17 +131,16 @@ public class LocalNotification extends CordovaPlugin {
                 if (action.equals("ready")) {
                     deviceready();
                 } else
-                if (action.equalsIgnoreCase("check")) {
+                if (action.equals("check")) {
                     check(command);
                 } else
-                if (action.equalsIgnoreCase("request")) {
+                if (action.equals("request")) {
                     request(command);
                 } else
-                if (action.equalsIgnoreCase("actions")) {
-                    actions(args.optJSONObject(0));
-                    command.success();
+                if (action.equals("actions")) {
+                    actions(args, command);
                 } else
-                if (action.equalsIgnoreCase("schedule")) {
+                if (action.equals("schedule")) {
                     schedule(args);
                     check(command);
                 } else
@@ -227,10 +226,8 @@ public class LocalNotification extends CordovaPlugin {
      *                JavaScript.
      */
     private void check (CallbackContext command) {
-        boolean allowed     = getNotMgr().hasPermission();
-        PluginResult result = new PluginResult(PluginResult.Status.OK, allowed);
-
-        command.sendPluginResult(result);
+        boolean allowed = getNotMgr().hasPermission();
+        success(command, allowed);
     }
 
     /**
@@ -246,13 +243,41 @@ public class LocalNotification extends CordovaPlugin {
     /**
      * Register action group.
      *
-     * @param args The action group spec.
+     * @param args    The exec() arguments in JSON form.
+     * @param command The callback context used when calling back into
+     *                JavaScript.
      */
-    private void actions (JSONObject args) {
-        ActionGroup group = ActionGroup.parse(cordova.getActivity(), args);
+    private void actions (JSONArray args, CallbackContext command) {
+        int task = args.optInt(0);
+
+        ActionGroup group;
+        JSONObject spec;
+        boolean found;
+        String id;
+
+        switch (task) {
+            case 1:
+                spec  = args.optJSONObject(1);
+                group = ActionGroup.parse(cordova.getActivity(), spec);
+
+                if (group != null) ActionGroup.register(group);
+                command.success();
+
+                break;
+            case -1:
+                id = args.optString(1);
+
+                ActionGroup.unregister(id);
+                command.success();
 
-        if (group != null) {
-            ActionGroup.register(group);
+                break;
+            case 0:
+                id = args.optString(1);
+
+                found = ActionGroup.isRegistered(id);
+                success(command, found);
+
+                break;
         }
     }
 
@@ -484,6 +509,18 @@ public class LocalNotification extends CordovaPlugin {
         eventQueue.clear();
     }
 
+    /**
+     * Invoke success callback with a single boolean argument.
+     *
+     * @param command The callback context used when calling back into
+     *                JavaScript.
+     * @param arg     The single argument to pass through.
+     */
+    private void success(CallbackContext command, boolean arg) {
+        PluginResult result = new PluginResult(PluginResult.Status.OK, arg);
+        command.sendPluginResult(result);
+    }
+
     /**
      * Fire given event on JS side. Does inform all event listeners.
      *

+ 13 - 11
src/android/notification/Options.java

@@ -596,24 +596,26 @@ public final class Options {
      * Gets the list of actions to display.
      */
     Action[] getActions() {
-        String groupId    = options.optString("actionGroupId", null);
-        JSONArray actions = options.optJSONArray("actions");
+        Object value      = options.opt("actions");
+        String groupId    = null;
+        JSONArray actions = null;
         ActionGroup group = null;
 
-        if (actions != null && actions.length() > 0) {
-            group = ActionGroup.parse(context, options);
+        if (value instanceof String) {
+            groupId = (String) value;
+        } else
+        if (value instanceof JSONArray) {
+            actions = (JSONArray) value;
         }
 
-        if (group == null && groupId != null) {
+        if (groupId != null) {
             group = ActionGroup.lookup(groupId);
+        } else
+        if (actions != null && actions.length() > 0) {
+            group = ActionGroup.parse(context, options);
         }
 
-        if (group != null) {
-            ActionGroup.register(group);
-            return group.getActions();
-        }
-
-        return null;
+        return (group != null) ? group.getActions() : null;
     }
 
     /**

+ 18 - 0
src/android/notification/action/ActionGroup.java

@@ -72,6 +72,24 @@ public final class ActionGroup {
         }
     }
 
+    /**
+     * Unregister the action group.
+     *
+     * @param id The id of the action group to remove.
+     */
+    public static void unregister (String id) {
+        groups.remove(id);
+    }
+
+    /**
+     * Check if a action group with that id is registered.
+     *
+     * @param id The id of the action group to check for.
+     */
+    public static boolean isRegistered (String id) {
+        return groups.containsKey(id);
+    }
+
     /**
      * Creates an action group by parsing the specified action specs.
      *

+ 2 - 2
src/android/notification/util/AssetUtil.java

@@ -106,7 +106,7 @@ public final class AssetUtil {
      */
     private Uri getUriFromPath(String path) {
         String absPath = path.replaceFirst("file://", "")
-                             .replaceFirst("\\?.*$", "");
+                .replaceFirst("\\?.*$", "");
         File file      = new File(absPath);
 
         if (!file.exists()) {
@@ -126,7 +126,7 @@ public final class AssetUtil {
      */
     private Uri getUriFromAsset(String path) {
         String resPath  = path.replaceFirst("file:/", "www")
-                              .replaceFirst("\\?.*$", "");
+                .replaceFirst("\\?.*$", "");
         String fileName = resPath.substring(resPath.lastIndexOf('/') + 1);
         File file       = getTmpFile(fileName);
 

+ 51 - 20
src/ios/APPLocalNotification.m

@@ -176,7 +176,7 @@ UNNotificationPresentationOptions const OptionAlert = UNNotificationPresentation
 - (void) clearAll:(CDVInvokedUrlCommand*)command
 {
     [self.commandDelegate runInBackground:^{
-        [_center clearAllNotifications];
+        [_center clearNotifications];
         [self clearApplicationIconBadgeNumber];
         [self fireEvent:@"clearall"];
         [self execCallback:command];
@@ -217,7 +217,7 @@ UNNotificationPresentationOptions const OptionAlert = UNNotificationPresentation
 - (void) cancelAll:(CDVInvokedUrlCommand*)command
 {
     [self.commandDelegate runInBackground:^{
-        [_center cancelAllNotifications];
+        [_center cancelNotifications];
         [self clearApplicationIconBadgeNumber];
         [self fireEvent:@"cancelall"];
         [self execCallback:command];
@@ -408,15 +408,10 @@ UNNotificationPresentationOptions const OptionAlert = UNNotificationPresentation
 {
     [_center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings* settings) {
         BOOL authorized = settings.authorizationStatus == UNAuthorizationStatusAuthorized;
-        BOOL enabled = settings.notificationCenterSetting == UNNotificationSettingEnabled;
-        BOOL permitted = authorized && enabled;
+        BOOL enabled    = settings.notificationCenterSetting == UNNotificationSettingEnabled;
+        BOOL permitted  = authorized && enabled;
 
-        CDVPluginResult* result;
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
-                                     messageAsBool:permitted];
-
-        [self.commandDelegate sendPluginResult:result
-                                    callbackId:command.callbackId];
+        [self execCallback:command arg:permitted];
     }];
 }
 
@@ -443,14 +438,37 @@ UNNotificationPresentationOptions const OptionAlert = UNNotificationPresentation
 - (void) actions:(CDVInvokedUrlCommand *)command
 {
     [self.commandDelegate runInBackground:^{
-        NSDictionary* options = command.arguments[0];
+        int task              = [command.arguments[0] intValue];
         APPNotificationContent* notification;
+        NSDictionary* options;
+        NSString* identifier;
+        BOOL found;
 
-        notification = [[APPNotificationContent alloc]
-                        initWithOptions:options];
+        switch (task) {
+            case 1:
+                options      = command.arguments[1];
+                notification = [[APPNotificationContent alloc]
+                                initWithOptions:options];
 
-        [_center addNotificationCategory:notification.category];
-        [self execCallback:command];
+                [_center addActionGroup:notification.category];
+                [self execCallback:command];
+
+                break;
+            case -1:
+                identifier = command.arguments[1];
+
+                [_center removeActionGroup:identifier];
+                [self execCallback:command];
+
+                break;
+            case 0:
+                identifier = command.arguments[1];
+
+                found = [_center hasActionGroup:identifier];
+                [self execCallback:command arg:found];
+
+                break;
+        }
     }];
 }
 
@@ -466,11 +484,9 @@ UNNotificationPresentationOptions const OptionAlert = UNNotificationPresentation
  */
 - (void) scheduleNotification:(APPNotificationContent*)notification
 {
-    __weak APPLocalNotification* weakSelf  = self;
-    UNNotificationRequest* request = notification.request;
-    NSString* event = [request wasUpdated] ? @"update" : @"add";
-
-    [_center addNotificationCategory:notification.category];
+    __weak APPLocalNotification* weakSelf = self;
+    UNNotificationRequest* request        = notification.request;
+    NSString* event                       = [request wasUpdated] ? @"update" : @"add";
 
     [_center addNotificationRequest:request withCompletionHandler:^(NSError* e) {
         __strong APPLocalNotification* strongSelf = weakSelf;
@@ -641,6 +657,21 @@ UNNotificationPresentationOptions const OptionAlert = UNNotificationPresentation
                                 callbackId:command.callbackId];
 }
 
+/**
+ * Invokes the callback with a single boolean parameter.
+ *
+ * @return [ Void ]
+ */
+- (void) execCallback:(CDVInvokedUrlCommand*)command arg:(BOOL)arg
+{
+    CDVPluginResult *result = [CDVPluginResult
+                               resultWithStatus:CDVCommandStatus_OK
+                               messageAsBool:arg];
+
+    [self.commandDelegate sendPluginResult:result
+                                callbackId:command.callbackId];
+}
+
 /**
  * Fire general event.
  *

+ 1 - 1
src/ios/APPNotificationContent.m

@@ -64,7 +64,7 @@ static char optionsKey;
     self.sound              = options.sound;
     self.badge              = options.badge;
     self.attachments        = options.attachments;
-    self.categoryIdentifier = options.categoryId;
+    self.categoryIdentifier = options.actionGroupId;
 }
 
 #pragma mark -

+ 14 - 14
src/ios/APPNotificationOptions.h

@@ -23,21 +23,21 @@
 
 @interface APPNotificationOptions : NSObject
 
-@property (readonly, getter=id)          NSNumber*            id;
-@property (readonly, getter=identifier)  NSString*            identifier;
-@property (readonly, getter=categoryId)  NSString*            categoryId;
-@property (readonly, getter=title)       NSString*            title;
-@property (readonly, getter=subtitle)    NSString*            subtitle;
-@property (readonly, getter=badge)       NSNumber*            badge;
-@property (readonly, getter=text)        NSString*            text;
-@property (readonly, getter=silent)      BOOL                 silent;
-@property (readonly, getter=priority)    int                  priority;
-@property (readonly, getter=sound)       UNNotificationSound* sound;
-@property (readonly, getter=userInfo)    NSDictionary*        userInfo;
-@property (readonly, getter=actions)     NSArray<UNNotificationAction *> * actions;
-@property (readonly, getter=attachments) NSArray<UNNotificationAttachment *> * attachments;
+@property (readonly, getter=id)            NSNumber*            id;
+@property (readonly, getter=identifier)    NSString*            identifier;
+@property (readonly, getter=actionGroupId) NSString*            actionGroupId;
+@property (readonly, getter=title)         NSString*            title;
+@property (readonly, getter=subtitle)      NSString*            subtitle;
+@property (readonly, getter=badge)         NSNumber*            badge;
+@property (readonly, getter=text)          NSString*            text;
+@property (readonly, getter=silent)        BOOL                 silent;
+@property (readonly, getter=priority)      int                  priority;
+@property (readonly, getter=sound)         UNNotificationSound* sound;
+@property (readonly, getter=userInfo)      NSDictionary*        userInfo;
+@property (readonly, getter=actions)       NSArray<UNNotificationAction*>*actions;
+@property (readonly, getter=attachments)   NSArray<UNNotificationAttachment*>*attachments;
 
-- (id) initWithDict:(NSDictionary*)dict;
+- (id) initWithDict:(NSDictionary*) dict;
 - (UNNotificationTrigger*) trigger;
 
 @end

+ 7 - 5
src/ios/APPNotificationOptions.m

@@ -51,12 +51,9 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
  */
 - (id) initWithDict:(NSDictionary*)dictionary
 {
-    self = [self init];
-
+    self      = [self init];
     self.dict = dictionary;
 
-    [self actions];
-
     return self;
 }
 
@@ -154,8 +151,13 @@ static NSInteger WEEKDAYS[8] = { 0, 2, 3, 4, 5, 6, 7, 1 };
  *
  * @return [ NSString* ]
  */
-- (NSString*) categoryId
+- (NSString*) actionGroupId
 {
+    id actions = [dict objectForKey:@"actions"];
+    
+    if ([actions isKindOfClass:NSString.class])
+        return actions;
+    
     NSString* value = [dict objectForKey:@"actionGroupId"];
 
     return value.length ? value : kAPPGeneralCategory;

+ 0 - 3
src/ios/UNNotificationRequest+APPLocalNotification.h

@@ -25,11 +25,8 @@
 
 @interface UNNotificationRequest (APPLocalNotification)
 
-// The options provided by the plug-in
 - (APPNotificationOptions*) options;
-// If the notification was updated
 - (BOOL) wasUpdated;
-// Encode the user info dict to JSON
 - (NSString*) encodeToJSON;
 
 @end

+ 5 - 15
src/ios/UNUserNotificationCenter+APPLocalNotification.h

@@ -37,34 +37,24 @@ typedef NS_ENUM(NSUInteger, APPNotificationType) {
 @property (readonly, getter=getNotifications) NSArray* localNotifications;
 @property (readonly, getter=getNotificationIds) NSArray* localNotificationIds;
 
-// Register general notification category to listen for dismiss actions
 - (void) registerGeneralNotificationCategory;
-// Add the specified category to the list of categories
-- (void) addNotificationCategory:(UNNotificationCategory*)category;
+- (void) addActionGroup:(UNNotificationCategory*)category;
+- (void) removeActionGroup:(NSString*)identifier;
+- (BOOL) hasActionGroup:(NSString*)identifier;
 
-// List of all notification IDs from given type
 - (NSArray*) getNotificationIdsByType:(APPNotificationType)type;
 
-// Find notification by ID
 - (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id;
-// Find notification type by ID
 - (APPNotificationType) getTypeOfNotificationWithId:(NSNumber*)id;
 
-// Property list from all local notifications
 - (NSArray*) getNotificationOptions;
-// Property list from given local notifications
 - (NSArray*) getNotificationOptionsById:(NSArray*)ids;
-// Property list from all local notifications with type constraint
 - (NSArray*) getNotificationOptionsByType:(APPNotificationType)type;
 
-// Clear specified notfication
 - (void) clearNotification:(UNNotificationRequest*)notification;
-// Clear all notfications
-- (void) clearAllNotifications;
+- (void) clearNotifications;
 
-// Cancel specified notfication
 - (void) cancelNotification:(UNNotificationRequest*)notification;
-// Cancel all notfications
-- (void) cancelAllNotifications;
+- (void) cancelNotifications;
 
 @end

+ 59 - 5
src/ios/UNUserNotificationCenter+APPLocalNotification.m

@@ -56,7 +56,7 @@ NSString * const kAPPGeneralCategory = @"GENERAL";
  *
  * @return [ Void ]
  */
-- (void) addNotificationCategory:(UNNotificationCategory*)category
+- (void) addActionGroup:(UNNotificationCategory*)category
 {
     if (!category)
         return;
@@ -64,7 +64,8 @@ NSString * const kAPPGeneralCategory = @"GENERAL";
     [self getNotificationCategoriesWithCompletionHandler:^(NSSet<UNNotificationCategory *> *set) {
         NSMutableSet* categories = [NSMutableSet setWithSet:set];
 
-        for (UNNotificationCategory* item in categories) {
+        for (UNNotificationCategory* item in categories)
+        {
             if ([category.identifier isEqualToString:item.identifier]) {
                 [categories removeObject:item];
                 break;
@@ -76,6 +77,58 @@ NSString * const kAPPGeneralCategory = @"GENERAL";
     }];
 }
 
+/**
+ * Remove if the specified category does exist.
+ *
+ * @param [ NSString* ] identifier The category id to remove.
+ *
+ * @return [ Void ]
+ */
+- (void) removeActionGroup:(NSString*)identifier
+{
+    [self getNotificationCategoriesWithCompletionHandler:^(NSSet<UNNotificationCategory *> *set) {
+        NSMutableSet* categories = [NSMutableSet setWithSet:set];
+        
+        for (UNNotificationCategory* item in categories)
+        {
+            if ([item.identifier isEqualToString:identifier]) {
+                [categories removeObject:item];
+                break;
+            }
+        }
+
+        [self setNotificationCategories:categories];
+    }];
+}
+
+/**
+ * Check if the specified category does exist.
+ *
+ * @param [ NSString* ] identifier The category id to check for.
+ *
+ * @return [ Void ]
+ */
+- (BOOL) hasActionGroup:(NSString*)identifier
+{
+    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
+    __block BOOL found        = NO;
+
+    [self getNotificationCategoriesWithCompletionHandler:^(NSSet<UNNotificationCategory *> *items) {
+        for (UNNotificationCategory* item in items)
+        {
+            if ([item.identifier isEqualToString:identifier]) {
+                found = YES;
+                dispatch_semaphore_signal(sema);
+                break;
+            }
+        }
+    }];
+    
+    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
+    
+    return found;
+}
+
 #pragma mark -
 #pragma mark LocalNotifications
 
@@ -101,7 +154,8 @@ NSString * const kAPPGeneralCategory = @"GENERAL";
     dispatch_semaphore_t sema = dispatch_semaphore_create(0);
 
     [self getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> *delivered) {
-        for (UNNotification* notification in delivered) {
+        for (UNNotification* notification in delivered)
+        {
             [notifications addObject:notification.request];
         }
         dispatch_semaphore_signal(sema);
@@ -276,7 +330,7 @@ NSString * const kAPPGeneralCategory = @"GENERAL";
 /*
  * Clear all notfications.
  */
-- (void) clearAllNotifications
+- (void) clearNotifications
 {
     [self removeAllDeliveredNotifications];
 }
@@ -298,7 +352,7 @@ NSString * const kAPPGeneralCategory = @"GENERAL";
 /*
  * Cancel all notfications.
  */
-- (void) cancelAllNotifications
+- (void) cancelNotifications
 {
     [self removeAllPendingNotificationRequests];
     [self removeAllDeliveredNotifications];

+ 30 - 6
www/local-notification.js

@@ -24,7 +24,6 @@ var exec    = require('cordova/exec'),
 
 // Defaults
 exports._defaults = {
-    actionGroupId : null,
     actions       : [],
     attachments   : [],
     autoClear     : true,
@@ -384,7 +383,7 @@ exports.getTriggered = function (callback, scope) {
 };
 
 /**
- * Register an group of actions by id.
+ * Add an group of actions by id.
  *
  * @param [ String ]   id       The Id of the group.
  * @param [ Array]     actions  The action config settings.
@@ -393,10 +392,35 @@ exports.getTriggered = function (callback, scope) {
  *
  * @return [ Void ]
  */
-exports.addActionGroup = function (id, actions, callback, scope) {
+exports.addActions = function (id, actions, callback, scope) {
     var config = { actionGroupId: id, actions: actions };
+    this._exec('actions', [1, config], callback, scope);
+};
 
-    this._exec('actions', config, callback, scope);
+/**
+ * Remove an group of actions by id.
+ *
+ * @param [ String ]   id       The Id of the group.
+ * @param [ Function ] callback The function to be exec as the callback.
+ * @param [ Object ]   scope    The callback function's scope.
+ *
+ * @return [ Void ]
+ */
+exports.removeActions = function (id, callback, scope) {
+    this._exec('actions', [-1, id], callback, scope);
+};
+
+/**
+ * Check if a group of actions is defined.
+ *
+ * @param [ String ]   id       The Id of the group.
+ * @param [ Function ] callback The function to be exec as the callback.
+ * @param [ Object ]   scope    The callback function's scope.
+ *
+ * @return [ Void ]
+ */
+exports.hasActions = function (id, callback, scope) {
+    this._exec('actions', [0, id], callback, scope);
 };
 
 /**
@@ -651,8 +675,8 @@ exports._convertPriority = function (options) {
 exports._convertActions = function (options) {
     var actions = [];
 
-    if (!options.actions)
-        return null;
+    if (!options.actions || typeof options.actions === 'string')
+        return options;
 
     for (var i = 0, len = options.actions.length; i < len; i++) {
         var action = options.actions[i];