Commit 008a0ec0 by Sebastián Katzer

Update to latest work in progress

parent 58f57589
...@@ -2,121 +2,141 @@ ...@@ -2,121 +2,141 @@
"images" : [ "images" : [
{ {
"idiom" : "iphone", "idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"size" : "29x29", "size" : "29x29",
"idiom" : "iphone",
"filename" : "icon-small.png", "filename" : "icon-small.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "iphone",
"size" : "29x29", "size" : "29x29",
"idiom" : "iphone",
"filename" : "icon-small@2x.png", "filename" : "icon-small@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "iphone",
"size" : "29x29", "size" : "29x29",
"idiom" : "iphone",
"filename" : "icon-small@3x.png", "filename" : "icon-small@3x.png",
"scale" : "3x" "scale" : "3x"
}, },
{ {
"idiom" : "iphone",
"size" : "40x40", "size" : "40x40",
"idiom" : "iphone",
"filename" : "icon-40@2x.png", "filename" : "icon-40@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "iphone",
"size" : "40x40", "size" : "40x40",
"idiom" : "iphone",
"filename" : "icon-60@2x.png", "filename" : "icon-60@2x.png",
"scale" : "3x" "scale" : "3x"
}, },
{ {
"idiom" : "iphone",
"size" : "57x57", "size" : "57x57",
"idiom" : "iphone",
"filename" : "icon.png", "filename" : "icon.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "iphone",
"size" : "57x57", "size" : "57x57",
"idiom" : "iphone",
"filename" : "icon@2x.png", "filename" : "icon@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "iphone",
"size" : "60x60", "size" : "60x60",
"idiom" : "iphone",
"filename" : "icon-60@2x.png", "filename" : "icon-60@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "iphone",
"size" : "60x60", "size" : "60x60",
"idiom" : "iphone",
"filename" : "icon-60@3x.png", "filename" : "icon-60@3x.png",
"scale" : "3x" "scale" : "3x"
}, },
{ {
"idiom" : "ipad", "idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"size" : "29x29", "size" : "29x29",
"idiom" : "ipad",
"filename" : "icon-small.png", "filename" : "icon-small.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "29x29", "size" : "29x29",
"idiom" : "ipad",
"filename" : "icon-small@2x.png", "filename" : "icon-small@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "40x40", "size" : "40x40",
"idiom" : "ipad",
"filename" : "icon-40.png", "filename" : "icon-40.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "40x40", "size" : "40x40",
"idiom" : "ipad",
"filename" : "icon-40@2x.png", "filename" : "icon-40@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "50x50", "size" : "50x50",
"idiom" : "ipad",
"filename" : "icon-50.png", "filename" : "icon-50.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "50x50", "size" : "50x50",
"idiom" : "ipad",
"filename" : "icon-50@2x.png", "filename" : "icon-50@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "72x72", "size" : "72x72",
"idiom" : "ipad",
"filename" : "icon-72.png", "filename" : "icon-72.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "72x72", "size" : "72x72",
"idiom" : "ipad",
"filename" : "icon-72@2x.png", "filename" : "icon-72@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "76x76", "size" : "76x76",
"idiom" : "ipad",
"filename" : "icon-76.png", "filename" : "icon-76.png",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"idiom" : "ipad",
"size" : "76x76", "size" : "76x76",
"idiom" : "ipad",
"filename" : "icon-76@2x.png", "filename" : "icon-76@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"idiom" : "ipad",
"size" : "83.5x83.5", "size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "icon-83.5@2x.png", "filename" : "icon-83.5@2x.png",
"scale" : "2x" "scale" : "2x"
}, },
......
/* /*
* Copyright (c) 2013 by appPlant GmbH. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code * This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License * as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in * Version 2.0 (the 'License'). You may not use this file except in
...@@ -13,6 +17,8 @@ ...@@ -13,6 +17,8 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and * Please see the License for the specific language governing rights and
* limitations under the License. * limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/ */
#import <Cordova/CDVPlugin.h> #import <Cordova/CDVPlugin.h>
...@@ -29,45 +35,45 @@ ...@@ -29,45 +35,45 @@
// Request permission to show notifications // Request permission to show notifications
- (void) request:(CDVInvokedUrlCommand*)command; - (void) request:(CDVInvokedUrlCommand*)command;
//// Schedule set of notifications // Schedule notifications
//- (void) schedule:(CDVInvokedUrlCommand*)command; - (void) schedule:(CDVInvokedUrlCommand*)command;
//// Update set of notifications //// Update set of notifications
//- (void) update:(CDVInvokedUrlCommand*)command; //- (void) update:(CDVInvokedUrlCommand*)command;
//// Cancel set of notifications // Clear notifications by id
//- (void) cancel:(CDVInvokedUrlCommand*)command; - (void) clear:(CDVInvokedUrlCommand*)command;
//// Cancel all notifications // Clear all notifications
//- (void) cancelAll:(CDVInvokedUrlCommand*)command; - (void) clearAll:(CDVInvokedUrlCommand*)command;
//// Clear set of notifications // Cancel notifications by id
//- (void) clear:(CDVInvokedUrlCommand*)command; - (void) cancel:(CDVInvokedUrlCommand*)command;
//// Clear all notifications // Cancel all notifications
//- (void) clearAll:(CDVInvokedUrlCommand*)command; - (void) cancelAll:(CDVInvokedUrlCommand*)command;
//
//// If a notification with an ID is present // If a notification with an ID is present
//- (void) isPresent:(CDVInvokedUrlCommand*)command; - (void) isPresent:(CDVInvokedUrlCommand*)command;
//// If a notification with an ID is scheduled // If a notification with an ID is scheduled
//- (void) isScheduled:(CDVInvokedUrlCommand*)command; - (void) isScheduled:(CDVInvokedUrlCommand*)command;
//// If a notification with an ID is triggered // If a notification with an ID is triggered
//- (void) isTriggered:(CDVInvokedUrlCommand*)command; - (void) isTriggered:(CDVInvokedUrlCommand*)command;
//
//// List all ids from all local notifications // List of all notification IDs
//- (void) getAllIds:(CDVInvokedUrlCommand*)command; - (void) ids:(CDVInvokedUrlCommand*)command;
//// List all ids from all pending notifications // List of all scheduled notification IDs
//- (void) getScheduledIds:(CDVInvokedUrlCommand*)command; - (void) scheduledIds:(CDVInvokedUrlCommand*)command;
//// List all ids from all triggered notifications // List of all triggered notification IDs
//- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command; - (void) triggeredIds:(CDVInvokedUrlCommand*)command;
//
//// Propertys for given local notification // Notification by id
//- (void) getSingle:(CDVInvokedUrlCommand*)command; - (void) notification:(CDVInvokedUrlCommand*)command;
//// Propertya for given scheduled notification // Scheduled notification by id
//- (void) getSingleScheduled:(CDVInvokedUrlCommand*)command; - (void) scheduledNotification:(CDVInvokedUrlCommand*)command;
//// Propertys for given triggered notification // Triggered notification by id
//- (void) getSingleTriggered:(CDVInvokedUrlCommand*)command; - (void) triggeredNotification:(CDVInvokedUrlCommand*)command;
//
//// Property list for given local notifications // List of notifications by id
//- (void) getAll:(CDVInvokedUrlCommand*)command; - (void) notifications:(CDVInvokedUrlCommand*)command;
//// Property list for given scheduled notifications // List of scheduled notifications by id
//- (void) getScheduled:(CDVInvokedUrlCommand*)command; - (void) scheduledNotifications:(CDVInvokedUrlCommand*)command;
//// Property list for given triggered notifications // List of triggered notifications by id
//- (void) getTriggered:(CDVInvokedUrlCommand*)command; - (void) triggeredNotifications:(CDVInvokedUrlCommand*)command;
@end @end
...@@ -21,27 +21,14 @@ ...@@ -21,27 +21,14 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import <UserNotifications/UNNotificationSound.h> #import "APPNotificationOptions.h"
#import <UserNotifications/UNNotificationRequest.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface APPLocalNotificationOptions : NSObject @import UserNotifications;
- (id) initWithDict:(NSDictionary*)dict; @interface APPNotificationContent : UNMutableNotificationContent
@property (readonly, getter=id) NSNumber* id; - (id) initWithOptions:(NSDictionary*)dict;
@property (readonly, getter=identifier) NSString* identifier; - (APPNotificationOptions*) options;
@property (readonly, getter=title) NSString* title; - (UNNotificationRequest*) request;
@property (readonly, getter=subtitle) NSString* subtitle;
@property (readonly, getter=badge) NSNumber* badge;
@property (readonly, getter=text) NSString* text;
@property (readonly, getter=sound) UNNotificationSound* sound;
@property (readonly, getter=userInfo) NSDictionary* userInfo;
// If it's a repeating notification
- (BOOL) isRepeating;
// how and when to trigger the notification
- (UNNotificationTrigger*) trigger;
@end @end
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationContent.h"
#import "APPNotificationOptions.h"
#import "UNUserNotificationCenter+APPLocalNotification.h"
#import <objc/runtime.h>
@import UserNotifications;
static char optionsKey;
@implementation APPNotificationContent : UNMutableNotificationContent
#pragma mark -
#pragma mark Init
/**
* Initialize a notification with the given options.
*
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ UNMutableNotificationContent ]
*/
- (id) initWithOptions:(NSDictionary*)dict
{
self = [self init];
[self setUserInfo:dict];
[self __init];
return self;
}
/**
* Initialize a notification by using the options found under userInfo.
*
* @return [ Void ]
*/
- (void) __init
{
APPNotificationOptions* options = self.options;
self.title = options.title;
self.subtitle = options.subtitle;
self.body = options.text;
self.sound = options.sound;
self.badge = options.badge;
self.attachments = options.attachments;
self.categoryIdentifier = kAPPGeneralCategory;
}
#pragma mark -
#pragma mark Public
/**
* The options used to initialize the notification.
*
* @return [ APPNotificationOptions* ] options
*/
- (APPNotificationOptions*) options
{
APPNotificationOptions* options = [self getOptions];
if (!options) {
options = [[APPNotificationOptions alloc]
initWithDict:[self userInfo]];
[self setOptions:options];
}
return options;
}
/**
* The notifcations request ready to add to the notification center including
* all informations about trigger behavior.
*
* @return [ UNNotificationRequest* ]
*/
- (UNNotificationRequest*) request
{
APPNotificationOptions* opts = [self getOptions];
return [UNNotificationRequest requestWithIdentifier:opts.identifier
content:self
trigger:opts.trigger];
}
#pragma mark -
#pragma mark Private
/**
* The options used to initialize the notification.
*
* @return [ APPNotificationOptions* ]
*/
- (APPNotificationOptions*) getOptions
{
return objc_getAssociatedObject(self, &optionsKey);
}
/**
* Set the options used to initialize the notification.
*
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ Void ]
*/
- (void) setOptions:(APPNotificationOptions*)options
{
objc_setAssociatedObject(self, &optionsKey,
options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
...@@ -21,43 +21,21 @@ ...@@ -21,43 +21,21 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "UILocalNotification+APPLocalNotification.ios9.h" @import UserNotifications;
@interface UIApplication (APPLocalNotification) @interface APPNotificationOptions : NSObject
@property (readonly, getter=localNotifications) NSArray* localNotifications; @property (readonly, getter=id) NSNumber* id;
@property (readonly, getter=localNotificationIds) NSArray* localNotificationIds; @property (readonly, getter=identifier) NSString* identifier;
@property (readonly, getter=title) NSString* title;
// If the app has the permission to schedule local notifications @property (readonly, getter=subtitle) NSString* subtitle;
- (BOOL) hasPermissionToScheduleLocalNotifications; @property (readonly, getter=badge) NSNumber* badge;
// Ask for permission to schedule local notifications @property (readonly, getter=text) NSString* text;
- (void) registerPermissionToScheduleLocalNotifications; @property (readonly, getter=sound) UNNotificationSound* sound;
@property (readonly, getter=attachments) NSArray<UNNotificationAttachment *> * attachments;
// List of all local notification IDs from given type @property (readonly, getter=userInfo) NSDictionary* userInfo;
- (NSArray*) localNotificationIdsByType:(APPNotificationType)type;
- (id) initWithDict:(NSDictionary*)dict;
// If local notification with ID exists - (UNNotificationTrigger*) trigger;
- (BOOL) localNotificationExist:(NSNumber*)id;
// If local notification with ID and type exists
- (BOOL) localNotificationExist:(NSNumber*)id type:(APPNotificationType)type;
// Local notification by ID
- (UILocalNotification*) localNotificationWithId:(NSNumber*)id;
// Local notification by ID and type
- (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPNotificationType)type;
// Property list from all local notifications
- (NSArray*) localNotificationOptions;
// Property list from given local notifications
- (NSArray*) localNotificationOptionsById:(NSArray*)ids;
// Property list from all local notifications with type constraint
- (NSArray*) localNotificationOptionsByType:(APPNotificationType)type;
// Property list from given local notifications with type constraint
- (NSArray*) localNotificationOptionsByType:(APPNotificationType)type andId:(NSArray*)ids;
// Clear single local notfications
- (void) clearLocalNotification:(UILocalNotification*)notification;
// Clear all local notfications
- (void) clearAllLocalNotifications;
@end @end
...@@ -21,18 +21,14 @@ ...@@ -21,18 +21,14 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "APPLocalNotificationOptions.h" #import "APPNotificationOptions.h"
@import UserNotifications; @import UserNotifications;
@interface UNMutableNotificationContent (APPLocalNotification) @interface UNNotificationRequest (APPLocalNotification)
// Initialize a new local notification
- (id) initWithOptions:(NSDictionary*)dict;
// The options provided by the plug-in // The options provided by the plug-in
- (APPLocalNotificationOptions*) options; - (APPNotificationOptions*) options;
// Fully configured request to add the notification to the notification center
- (UNNotificationRequest*) request;
// Encode the user info dict to JSON // Encode the user info dict to JSON
- (NSString*) encodeToJSON; - (NSString*) encodeToJSON;
......
...@@ -21,62 +21,44 @@ ...@@ -21,62 +21,44 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "UNMutableNotificationContent+APPLocalNotification.h" #import "APPNotificationOptions.h"
#import "APPLocalNotificationOptions.h" #import "UNNotificationRequest+APPLocalNotification.h"
#import "APPNotificationContent.h"
#import <objc/runtime.h> #import <objc/runtime.h>
@import UserNotifications; @import UserNotifications;
static char optionsKey; static char optionsKey;
@implementation UNMutableNotificationContent (APPLocalNotification) @implementation UNNotificationRequest (APPLocalNotification)
#pragma mark -
#pragma mark Init
/** /**
* Initialize a local notification with the given options when calling on JS side: * Get associated option object
* notification.local.add(options)
*/ */
- (id) initWithOptions:(NSDictionary*)dict - (APPNotificationOptions*) getOptions
{ {
self = [self init]; return objc_getAssociatedObject(self, &optionsKey);
[self setUserInfo:dict];
[self __init];
return self;
} }
/** /**
* Applies the given options when calling on JS side: * Set associated option object
* notification.local.add(options)
*/ */
- (void) __init - (void) setOptions:(APPNotificationOptions*)options
{ {
APPLocalNotificationOptions* options = self.options; objc_setAssociatedObject(self, &optionsKey,
options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
self.title = options.title;
self.subtitle = options.subtitle;
self.body = options.text;
self.sound = options.sound;
self.badge = options.badge;
} }
#pragma mark -
#pragma mark Methods
/** /**
* The options provided by the plug-in. * The options provided by the plug-in.
*/ */
- (APPLocalNotificationOptions*) options - (APPNotificationOptions*) options
{ {
APPLocalNotificationOptions* options = [self getOptions]; APPNotificationOptions* options = [self getOptions];
if (!options) { if (!options) {
options = [[APPLocalNotificationOptions alloc] options = [[APPNotificationOptions alloc]
initWithDict:[self userInfo]]; initWithDict:[self.content userInfo]];
[self setOptions:options]; [self setOptions:options];
} }
...@@ -85,43 +67,13 @@ static char optionsKey; ...@@ -85,43 +67,13 @@ static char optionsKey;
} }
/** /**
* Get associated option object
*/
- (APPLocalNotificationOptions*) getOptions
{
return objc_getAssociatedObject(self, &optionsKey);
}
/**
* Set associated option object
*/
- (void) setOptions:(APPLocalNotificationOptions*)options
{
objc_setAssociatedObject(self, &optionsKey,
options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
/**
* The notifcations request ready to add to the notification center including
* all informations about trigger behavior.
*/
- (UNNotificationRequest*) request
{
APPLocalNotificationOptions* opts = [self getOptions];
return [UNNotificationRequest requestWithIdentifier:opts.identifier
content:self
trigger:opts.trigger];
}
/**
* Encode the user info dict to JSON. * Encode the user info dict to JSON.
*/ */
- (NSString*) encodeToJSON - (NSString*) encodeToJSON
{ {
NSString* json; NSString* json;
NSData* data; NSData* data;
NSMutableDictionary* obj = [self.userInfo mutableCopy]; NSMutableDictionary* obj = [self.content.userInfo mutableCopy];
[obj removeObjectForKey:@"updatedAt"]; [obj removeObjectForKey:@"updatedAt"];
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationContent.h"
@interface UNUserNotificationCenter (APPLocalNotification)
extern NSString * const kAPPGeneralCategory;
typedef NS_ENUM(NSUInteger, APPNotificationType) {
NotifcationTypeAll = 0,
NotifcationTypeScheduled = 1,
NotifcationTypeTriggered = 2
};
#define APPNotificationType_DEFINED
@property (readonly, getter=getNotifications) NSArray* localNotifications;
@property (readonly, getter=getNotificationIds) NSArray* localNotificationIds;
- (void) registerGeneralNotificationCategory;
// List of all notification IDs from given type
- (NSArray*) getNotificationIdsByType:(APPNotificationType)type;
// Find out if notification with ID exists
- (BOOL) notificationExist:(NSNumber*)id;
// Find out if notification with ID and type exists
- (BOOL) notificationExist:(NSNumber*)id type:(APPNotificationType)type;
// Find notification by ID
- (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id;
// Find notification by ID and type
- (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id andType:(APPNotificationType)type;
// 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;
// Property list from given local notifications with type constraint
- (NSArray*) getNotificationOptionsByType:(APPNotificationType)type andId:(NSArray*)ids;
// Clear specified notfication
- (void) clearNotification:(UNNotificationRequest*)notification;
// Clear all notfications
- (void) clearAllNotifications;
// Cancel specified notfication
- (void) cancelNotification:(UNNotificationRequest*)notification;
// Cancel all notfications
- (void) cancelAllNotifications;
@end
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "UNUserNotificationCenter+APPLocalNotification.h"
#import "UNNotificationRequest+APPLocalNotification.h"
@import UserNotifications;
NSString * const kAPPGeneralCategory = @"GENERAL";
@implementation UNUserNotificationCenter (APPLocalNotification)
#pragma mark -
#pragma mark NotificationCategory
/**
* Register general notification category to listen for dismiss actions.
*
* @return [ Void ]
*/
- (void) registerGeneralNotificationCategory
{
UNNotificationCategory* category;
category = [UNNotificationCategory
categoryWithIdentifier:kAPPGeneralCategory
actions:@[]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
[self setNotificationCategories:[NSSet setWithObjects:category, nil]];
}
#pragma mark -
#pragma mark LocalNotifications
/**
* List of all delivered or still pending notifications.
*/
- (NSArray*) getNotifications
{
NSMutableArray* notifications = [[NSMutableArray alloc] init];
[notifications addObjectsFromArray:[self getPendingNotifications]];
[notifications addObjectsFromArray:[self getDeliveredNotifications]];
return notifications;
}
/**
* List of all triggered notifications.
*/
- (NSArray*) getDeliveredNotifications
{
NSMutableArray* notifications = [[NSMutableArray alloc] init];
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[self getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> *delivered) {
for (UNNotification* notification in delivered) {
[notifications addObject:notification.request];
}
dispatch_semaphore_signal(sema);
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
return notifications;
}
/**
* List of all pending notifications.
*/
- (NSArray*) getPendingNotifications
{
NSMutableArray* notifications = [[NSMutableArray alloc] init];
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[self getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> *requests) {
[notifications addObjectsFromArray:requests];
dispatch_semaphore_signal(sema);
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
return notifications;
}
/**
* List of all notifications from given type.
*
* @param type
* Notification life cycle type
*/
- (NSArray*) getNotificationsByType:(APPNotificationType)type
{
switch (type) {
case NotifcationTypeScheduled:
return [self getPendingNotifications];
case NotifcationTypeTriggered:
return [self getDeliveredNotifications];
default:
return [self getNotifications];
}
}
/**
* List of all local notifications IDs.
*/
- (NSArray*) getNotificationIds
{
NSArray* notifications = [self getNotifications];
NSMutableArray* ids = [[NSMutableArray alloc] init];
for (UNNotificationRequest* notification in notifications)
{
[ids addObject:notification.options.id];
}
return ids;
}
/**
* List of all notifications IDs from given type.
*
* @param type
* Notification life cycle type
*/
- (NSArray*) getNotificationIdsByType:(APPNotificationType)type
{
NSArray* notifications = [self getNotificationsByType:type];
NSMutableArray* ids = [[NSMutableArray alloc] init];
for (UNNotificationRequest* notification in notifications)
{
[ids addObject:notification.options.id];
}
return ids;
}
/*
* If the notification with the specified ID does exists.
*
* @param id
* Notification ID
*/
- (BOOL) notificationExist:(NSNumber*)id
{
return [self getNotificationWithId:id] != NULL;
}
/* If the notification with specified ID and type exists.
*
* @param id
* Notification ID
* @param type
* Notification life cycle type
*/
- (BOOL) notificationExist:(NSNumber*)id type:(APPNotificationType)type
{
return [self getNotificationWithId:id andType:type] != NULL;
}
/**
* Find notification by ID.
*
* @param id
* Notification ID
*/
- (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id
{
return [self getNotificationWithId:id andType:NotifcationTypeAll];
}
/*
* Find notification by ID and type.
*
* @param id
* Notification ID
* @param type
* Notification life cycle type
*/
- (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id andType:(APPNotificationType)type
{
NSArray* notifications = [self getNotificationsByType:type];
for (UNNotificationRequest* notification in notifications)
{
NSString* fid = [NSString stringWithFormat:@"%@", notification.options.id];
if ([fid isEqualToString:[id stringValue]]) {
return notification;
}
}
return NULL;
}
/**
* List of properties from all notifications.
*/
- (NSArray*) getNotificationOptions
{
return [self getNotificationOptionsByType:NotifcationTypeAll];
}
/**
* List of properties from all notifications of given type.
*
* @param type
* Notification life cycle type
*/
- (NSArray*) getNotificationOptionsByType:(APPNotificationType)type
{
NSArray* notifications = [self getNotificationsByType:type];
NSMutableArray* options = [[NSMutableArray alloc] init];
for (UNNotificationRequest* notification in notifications)
{
[options addObject:notification.options.userInfo];
}
return options;
}
/**
* List of properties from given local notifications.
*
* @param ids
* Notification IDs
*/
- (NSArray*) getNotificationOptionsById:(NSArray*)ids
{
return [self getNotificationOptionsByType:NotifcationTypeAll andId:ids];
}
/**
* List of properties from given local notifications.
*
* @param type
* Notification life cycle type
* @param ids
* Notification IDs
*/
- (NSArray*) getNotificationOptionsByType:(APPNotificationType)type andId:(NSArray*)ids
{
NSArray* notifications = [self getNotificationsByType:type];
NSMutableArray* options = [[NSMutableArray alloc] init];
for (UNNotificationRequest* notification in notifications)
{
if ([ids containsObject:notification.options.id]) {
[options addObject:notification.options.userInfo];
}
}
return options;
}
/*
* Clear all notfications.
*/
- (void) clearAllNotifications
{
[self removeAllDeliveredNotifications];
}
/*
* Clear Specified notfication.
*
* @param notification
* The notification object
*/
- (void) clearNotification:(UNNotificationRequest*)notification
{
NSArray* ids = [[NSArray alloc]
initWithObjects:notification.identifier, nil];
[self removeDeliveredNotificationsWithIdentifiers:ids];
}
/*
* Cancel all notfications.
*/
- (void) cancelAllNotifications
{
[self removeAllPendingNotificationRequests];
[self removeAllDeliveredNotifications];
}
/*
* Cancel specified notfication.
*
* @param notification
* The notification object
*/
- (void) cancelNotification:(UNNotificationRequest*)notification
{
NSArray* ids = [[NSArray alloc]
initWithObjects:notification.identifier, nil];
[self removeDeliveredNotificationsWithIdentifiers:ids];
[self removePendingNotificationRequestsWithIdentifiers:ids];
}
@end
cordova.define("cordova-plugin-local-notifications.LocalNotification.Util", function(require, exports, module) { cordova.define("cordova-plugin-local-notifications.LocalNotification.Util", function(require, exports, module) {
/* /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code * This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License * as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in * Version 2.0 (the 'License'). You may not use this file except in
...@@ -18,18 +14,11 @@ cordova.define("cordova-plugin-local-notifications.LocalNotification.Util", func ...@@ -18,18 +14,11 @@ cordova.define("cordova-plugin-local-notifications.LocalNotification.Util", func
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and * Please see the License for the specific language governing rights and
* limitations under the License. * limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/ */
var exec = require('cordova/exec'), var exec = require('cordova/exec'),
channel = require('cordova/channel'); channel = require('cordova/channel');
/***********
* MEMBERS *
***********/
// Default values // Default values
exports._defaults = { exports._defaults = {
text: '', text: '',
...@@ -42,22 +31,13 @@ exports._defaults = { ...@@ -42,22 +31,13 @@ exports._defaults = {
at: undefined at: undefined
}; };
// listener // Listener
exports._listener = {}; exports._listener = {};
// Registered permission flag
exports._registered = false;
/********
* UTIL *
********/
/** /**
* Merge platform specific properties into the default ones. * Merge platform specific properties into the default ones.
* *
* @return {Object} * @return [ Void ]
* The default properties for the platform
*/ */
exports.applyPlatformSpecificOptions = function () { exports.applyPlatformSpecificOptions = function () {
var defaults = this._defaults; var defaults = this._defaults;
...@@ -71,19 +51,18 @@ exports.applyPlatformSpecificOptions = function () { ...@@ -71,19 +51,18 @@ exports.applyPlatformSpecificOptions = function () {
defaults.led = undefined; defaults.led = undefined;
defaults.color = undefined; defaults.color = undefined;
break; break;
case 'iOS':
defaults.attachments = undefined;
break;
} }
return defaults;
}; };
/** /**
* Merge custom properties with the default values. * Merge custom properties with the default values.
* *
* @param {Object} options * @param [ Object ] options Set of custom values.
* Set of custom values
* *
* @retrun {Object} * @retrun [ Object ]
* The merged property list
*/ */
exports.mergeWithDefaults = function (options) { exports.mergeWithDefaults = function (options) {
var defaults = this.getDefaults(); var defaults = this.getDefaults();
...@@ -127,11 +106,9 @@ exports.mergeWithDefaults = function (options) { ...@@ -127,11 +106,9 @@ exports.mergeWithDefaults = function (options) {
/** /**
* Convert the passed values to their required type. * Convert the passed values to their required type.
* *
* @param {Object} options * @param [ Object ] options Properties to convert for.
* Set of custom values
* *
* @retrun {Object} * @return [ Object ] The converted property list
* The converted property list
*/ */
exports.convertProperties = function (options) { exports.convertProperties = function (options) {
...@@ -173,46 +150,33 @@ exports.convertProperties = function (options) { ...@@ -173,46 +150,33 @@ exports.convertProperties = function (options) {
options.data = JSON.stringify(options.data); options.data = JSON.stringify(options.data);
} }
if (options.every) {
if (device.platform == 'iOS' && typeof options.every != 'string') {
options.every = this.getDefaults().every;
var warning = 'Every option is not a string: ' + options.id;
warning += '. Expects one of: second, minute, hour, day, week, ';
warning += 'month, year on iOS.';
console.warn(warning);
}
}
return options; return options;
}; };
/** /**
* Create callback, which will be executed within a specific scope. * Create a callback function to get executed within a specific scope.
* *
* @param {Function} callbackFn * @param [ Function ] fn The function to be exec as the callback.
* The callback function * @param [ Object ] scope The callback function's scope.
* @param {Object} scope
* The scope for the function
* *
* @return {Function} * @return [ Function ]
* The new callback function
*/ */
exports.createCallbackFn = function (callbackFn, scope) { exports.createCallbackFn = function (fn, scope) {
if (typeof callbackFn != 'function') if (typeof fn != 'function')
return; return;
return function () { return function () {
callbackFn.apply(scope || this, arguments); fn.apply(scope || this, arguments);
}; };
}; };
/** /**
* Convert the IDs to numbers. * Convert the IDs to numbers.
* *
* @param {String/Number[]} ids * @param [ Array ] ids
* *
* @return Array of Numbers * @return [ Array<Number> ]
*/ */
exports.convertIds = function (ids) { exports.convertIds = function (ids) {
var convertedIds = []; var convertedIds = [];
...@@ -227,10 +191,10 @@ exports.convertIds = function (ids) { ...@@ -227,10 +191,10 @@ exports.convertIds = function (ids) {
/** /**
* First found value for the given keys. * First found value for the given keys.
* *
* @param {Object} options * @param [ Object ] options Object with key-value properties.
* Object with key-value properties * @param [ *Array<String> ] keys List of keys.
* @param {String[]} keys* *
* Key list * @return [ Object ]
*/ */
exports.getValueFor = function (options) { exports.getValueFor = function (options) {
var keys = Array.apply(null, arguments).slice(1); var keys = Array.apply(null, arguments).slice(1);
...@@ -245,12 +209,12 @@ exports.getValueFor = function (options) { ...@@ -245,12 +209,12 @@ exports.getValueFor = function (options) {
}; };
/** /**
* Fire event with given arguments. * Fire the event with given arguments.
* *
* @param {String} event * @param [ String ] event The event's name.
* The event's name * @param [ *Array] args The callback's arguments.
* @param {args*} *
* The callback's arguments * @return [ Void]
*/ */
exports.fireEvent = function (event) { exports.fireEvent = function (event) {
var args = Array.apply(null, arguments).slice(1), var args = Array.apply(null, arguments).slice(1),
...@@ -270,14 +234,12 @@ exports.fireEvent = function (event) { ...@@ -270,14 +234,12 @@ exports.fireEvent = function (event) {
/** /**
* Execute the native counterpart. * Execute the native counterpart.
* *
* @param {String} action * @param [ String ] action The name of the action.
* The name of the action * @param [ Array ] args Array of arguments.
* @param args[] * @param [ Function] callback The callback function.
* Array of arguments * @param [ Object ] scope The scope for the function.
* @param {Function} callback *
* The callback function * @return [ Void ]
* @param {Object} scope
* The scope for the function
*/ */
exports.exec = function (action, args, callback, scope) { exports.exec = function (action, args, callback, scope) {
var fn = this.createCallbackFn(callback, scope), var fn = this.createCallbackFn(callback, scope),
...@@ -292,11 +254,6 @@ exports.exec = function (action, args, callback, scope) { ...@@ -292,11 +254,6 @@ exports.exec = function (action, args, callback, scope) {
exec(fn, null, 'LocalNotification', action, params); exec(fn, null, 'LocalNotification', action, params);
}; };
/*********
* HOOKS *
*********/
// Called after 'deviceready' event // Called after 'deviceready' event
channel.deviceready.subscribe(function () { channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered // Device is ready now, the listeners are registered
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<body> <body>
<div> <div>
<div class="app"> <div class="app">
<h1>Local Notification Example</h1> <h1>Notification Example</h1>
<div id="deviceready" class="blink"> <div id="deviceready" class="blink">
<p class="event listening">Connecting to Device</p> <p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p> <p class="event received">Device is Ready</p>
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
<a id="sched_multi" class="button orange">Multiple</a> <a id="sched_multi" class="button orange">Multiple</a>
</div> </div>
<div class="container"> <div class="container">
<a id="sched_delay" class="button orange">Delayed</a> <a id="sched_delayed" class="button orange">Delayed</a>
<a id="sched_interval" class="button orange">Interval</a> <a id="sched_interval" class="button orange">Interval</a>
</div> </div>
<h2 class="section">Update</h2> <h2 class="section">Update</h2>
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
<a id="triggered_ids" class="button grey">Triggered</a> <a id="triggered_ids" class="button grey">Triggered</a>
</div> </div>
<div class="container"> <div class="container">
<a id="all_ids" class="button grey">All</a> <a id="ids" class="button grey">All</a>
</div> </div>
<h2 class="section">Notifications</h2> <h2 class="section">Notifications</h2>
<div class="container"> <div class="container">
...@@ -93,11 +93,11 @@ ...@@ -93,11 +93,11 @@
<a id="triggered_nots" class="button grey">Triggered</a> <a id="triggered_nots" class="button grey">Triggered</a>
</div> </div>
<div class="container"> <div class="container">
<a id="single_not" class="button grey">Single</a> <a id="notification" class="button grey">Single</a>
<a id="multiple_nots" class="button grey">Multiple</a> <a id="multiple_nots" class="button grey">Multiple</a>
</div> </div>
<div class="container"> <div class="container">
<a id="all_nots" class="button grey">All</a> <a id="notifications" class="button grey">All</a>
</div> </div>
<h2 class="section">Defaults</h2> <h2 class="section">Defaults</h2>
<div class="container"> <div class="container">
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
<!-- dependencies --> <!-- dependencies -->
<dependency id="cordova-plugin-device" /> <dependency id="cordova-plugin-device" />
<!-- <dependency id="cordova-plugin-app-event" /> -->
<!-- js --> <!-- js -->
<js-module src="www/local-notification.js" name="LocalNotification"> <js-module src="www/local-notification.js" name="LocalNotification">
...@@ -59,17 +58,17 @@ ...@@ -59,17 +58,17 @@
<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/APPLocalNotificationOptions.h" /> <header-file src="src/ios/APPNotificationContent.h" />
<source-file src="src/ios/APPLocalNotificationOptions.m" /> <source-file src="src/ios/APPNotificationContent.m" />
<header-file src="src/ios/APPNotificationOptions.h" />
<source-file src="src/ios/APPNotificationOptions.m" />
<header-file src="src/ios/UNUserNotificationCenter+APPLocalNotification.h" /> <header-file src="src/ios/UNUserNotificationCenter+APPLocalNotification.h" />
<source-file src="src/ios/UNUserNotificationCenter+APPLocalNotification.m" /> <source-file src="src/ios/UNUserNotificationCenter+APPLocalNotification.m" />
<header-file src="src/ios/UNMutableNotificationContent+APPLocalNotification.h" />
<source-file src="src/ios/UNMutableNotificationContent+APPLocalNotification.m" />
<header-file src="src/ios/UNNotificationRequest+APPLocalNotification.h" /> <header-file src="src/ios/UNNotificationRequest+APPLocalNotification.h" />
<source-file src="src/ios/UNNotificationRequest+APPLocalNotification.m" /> --> <source-file src="src/ios/UNNotificationRequest+APPLocalNotification.m" />
</platform> </platform>
......
/* /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved. * Copyright (c) 2013 by appPlant GmbH. All rights reserved.
* *
* @APPPLANT_LICENSE_HEADER_START@ * @APPPLANT_LICENSE_HEADER_START@
* *
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import <Foundation/Foundation.h>
#import <Cordova/CDVPlugin.h> #import <Cordova/CDVPlugin.h>
@import UserNotifications; @import UserNotifications;
...@@ -31,23 +30,23 @@ ...@@ -31,23 +30,23 @@
// Execute all queued events // Execute all queued events
- (void) deviceready:(CDVInvokedUrlCommand*)command; - (void) deviceready:(CDVInvokedUrlCommand*)command;
// Inform if the app has the permission to show notifications // Check permission to show notifications
- (void) hasPermission:(CDVInvokedUrlCommand*)command; - (void) check:(CDVInvokedUrlCommand*)command;
// Register permission to show notifications // Request permission to show notifications
- (void) registerPermission:(CDVInvokedUrlCommand*)command; - (void) request:(CDVInvokedUrlCommand*)command;
// Schedule set of notifications // Schedule notifications
- (void) schedule:(CDVInvokedUrlCommand*)command; - (void) schedule:(CDVInvokedUrlCommand*)command;
// Update set of notifications //// Update set of notifications
- (void) update:(CDVInvokedUrlCommand*)command; //- (void) update:(CDVInvokedUrlCommand*)command;
// Cancel set of notifications // Clear notifications by id
- (void) cancel:(CDVInvokedUrlCommand*)command;
// Cancel all notifications
- (void) cancelAll:(CDVInvokedUrlCommand*)command;
// Clear set of notifications
- (void) clear:(CDVInvokedUrlCommand*)command; - (void) clear:(CDVInvokedUrlCommand*)command;
// Clear all notifications // Clear all notifications
- (void) clearAll:(CDVInvokedUrlCommand*)command; - (void) clearAll:(CDVInvokedUrlCommand*)command;
// Cancel notifications by id
- (void) cancel:(CDVInvokedUrlCommand*)command;
// Cancel all notifications
- (void) cancelAll:(CDVInvokedUrlCommand*)command;
// If a notification with an ID is present // If a notification with an ID is present
- (void) isPresent:(CDVInvokedUrlCommand*)command; - (void) isPresent:(CDVInvokedUrlCommand*)command;
...@@ -56,25 +55,25 @@ ...@@ -56,25 +55,25 @@
// If a notification with an ID is triggered // If a notification with an ID is triggered
- (void) isTriggered:(CDVInvokedUrlCommand*)command; - (void) isTriggered:(CDVInvokedUrlCommand*)command;
// List all ids from all local notifications // List of all notification IDs
- (void) getAllIds:(CDVInvokedUrlCommand*)command; - (void) ids:(CDVInvokedUrlCommand*)command;
// List all ids from all pending notifications // List of all scheduled notification IDs
- (void) getScheduledIds:(CDVInvokedUrlCommand*)command; - (void) scheduledIds:(CDVInvokedUrlCommand*)command;
// List all ids from all triggered notifications // List of all triggered notification IDs
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command; - (void) triggeredIds:(CDVInvokedUrlCommand*)command;
// Propertys for given local notification // Notification by id
- (void) getSingle:(CDVInvokedUrlCommand*)command; - (void) notification:(CDVInvokedUrlCommand*)command;
// Propertya for given scheduled notification // Scheduled notification by id
- (void) getSingleScheduled:(CDVInvokedUrlCommand*)command; - (void) scheduledNotification:(CDVInvokedUrlCommand*)command;
// Propertys for given triggered notification // Triggered notification by id
- (void) getSingleTriggered:(CDVInvokedUrlCommand*)command; - (void) triggeredNotification:(CDVInvokedUrlCommand*)command;
// Property list for given local notifications // List of notifications by id
- (void) getAll:(CDVInvokedUrlCommand*)command; - (void) notifications:(CDVInvokedUrlCommand*)command;
// Property list for given scheduled notifications // List of scheduled notifications by id
- (void) getScheduled:(CDVInvokedUrlCommand*)command; - (void) scheduledNotifications:(CDVInvokedUrlCommand*)command;
// Property list for given triggered notifications // List of triggered notifications by id
- (void) getTriggered:(CDVInvokedUrlCommand*)command; - (void) triggeredNotifications:(CDVInvokedUrlCommand*)command;
@end @end
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPLocalNotificationOptions.h"
@import UserNotifications;
@interface APPLocalNotificationOptions ()
// The dictionary which contains all notification properties
@property(nonatomic, retain) NSDictionary* dict;
@end
@implementation APPLocalNotificationOptions
@synthesize dict;
#pragma mark -
#pragma mark Initialization
/**
* Initialize the object with the given options when calling on JS side:
* notification.local.add(options)
*/
- (id) initWithDict:(NSDictionary*)dictionary
{
self = [self init];
self.dict = dictionary;
return self;
}
#pragma mark -
#pragma mark Attributes
/**
* The notification's ID.
*/
- (NSNumber*) id
{
NSInteger id = [[dict objectForKey:@"id"] integerValue];
return [NSNumber numberWithInteger:id];
}
/**
* The notification's ID as a string.
*/
- (NSString*) identifier
{
return [NSString stringWithFormat:@"%@", self.id];
}
/**
* The notification's title.
*/
- (NSString*) title
{
return [dict objectForKey:@"title"];
}
/**
* The notification's title.
*/
- (NSString*) subtitle
{
NSArray *parts = [self.title componentsSeparatedByString:@"\n"];
return parts.count < 2 ? @"" : [parts objectAtIndex:1];
}
/**
* The notification's message.
*/
- (NSString*) text
{
return [dict objectForKey:@"text"];
}
/**
* The notification's badge number.
*/
- (NSNumber*) badge
{
return [NSNumber numberWithInt:[[dict objectForKey:@"badge"] intValue]];
}
/**
* The notification's sound path.
*/
- (UNNotificationSound*) sound
{
NSString* path = [dict objectForKey:@"sound"];
NSString* file;
if ([self stringIsNullOrEmpty:path])
return NULL;
if ([path isEqualToString:@"res://platform_default"])
return [UNNotificationSound defaultSound];
if ([path hasPrefix:@"file:/"]) {
file = [self soundNameForAsset:path];
} else
if ([path hasPrefix:@"res:"]) {
file = [self soundNameForResource:path];
}
return [UNNotificationSound soundNamed:file];
}
/**
* The notification's fire date.
*/
- (NSDate*) fireDate
{
double timestamp = [[dict objectForKey:@"at"]
doubleValue];
return [NSDate dateWithTimeIntervalSince1970:timestamp];
}
/**
* If it's a repeating notification.
*/
- (BOOL) isRepeating
{
NSString* interval = [dict objectForKey:@"every"];
return ![self stringIsNullOrEmpty:interval];
}
#pragma mark -
#pragma mark Methods
/**
* Specify how and when to trigger the notification.
*/
- (UNNotificationTrigger*) trigger
{
return [self isRepeating] ? [self triggerWithDateMatchingComponents] : [self triggerWithTimeInterval];
}
/**
* The notification's user info dict.
*/
- (NSDictionary*) userInfo
{
if ([dict objectForKey:@"updatedAt"]) {
NSMutableDictionary* data = [dict mutableCopy];
[data removeObjectForKey:@"updatedAt"];
return data;
}
return dict;
}
#pragma mark -
#pragma mark Private
/**
* Returns a trigger based on a custom time interval in seconds.
*/
- (UNTimeIntervalNotificationTrigger*) triggerWithTimeInterval
{
return [UNTimeIntervalNotificationTrigger
triggerWithTimeInterval:[self timeInterval] repeats:NO];
}
/**
* Returns a trigger based on a calendar time.
*/
- (UNCalendarNotificationTrigger*) triggerWithDateMatchingComponents
{
NSCalendar* cal = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *date = [cal components:[self repeatInterval]
fromDate:[self fireDate]];
[date setTimeZone:[NSTimeZone defaultTimeZone]];
return [UNCalendarNotificationTrigger
triggerWithDateMatchingComponents:date repeats:YES];
}
/**
* Timeinterval between future fire date and now.
*/
- (double) timeInterval
{
return MAX(0.01f, [self.fireDate timeIntervalSinceDate:[NSDate date]]);
}
/**
* The notification's repeat interval.
*/
- (NSCalendarUnit) repeatInterval
{
NSString* interval = [dict objectForKey:@"every"];
NSCalendarUnit unitFlags = NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond;
if ([self stringIsNullOrEmpty:interval]) {
return unitFlags;
}
else if ([interval isEqualToString:@"second"]) {
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay;
}
else if ([interval isEqualToString:@"minute"]) {
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitSecond;
}
else if ([interval isEqualToString:@"hour"]) {
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"day"]) {
return NSCalendarUnitHour|NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"week"]) {
return NSCalendarUnitWeekday|NSCalendarUnitHour|NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"month"]) {
return NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"year"]) {
return NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute;
}
return unitFlags;
}
/**
* Convert relative path to valid sound name attribute.
*/
- (NSString*) soundNameForAsset:(NSString*)path
{
return [path stringByReplacingOccurrencesOfString:@"file:/"
withString:@"www"];
}
/**
* Convert resource path to valid sound name attribute.
*/
- (NSString*) soundNameForResource:(NSString*)path
{
return [path pathComponents].lastObject;
}
/**
* If the string is empty.
*/
- (BOOL) stringIsNullOrEmpty:(NSString*)str
{
return (!str.length);
}
@end
...@@ -21,22 +21,14 @@ ...@@ -21,22 +21,14 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import <Foundation/Foundation.h> #import "APPNotificationOptions.h"
#import <UIKit/UIKit.h>
@interface APPLocalNotificationOptions9 : NSObject @import UserNotifications;
- (id) initWithDict:(NSDictionary*)dict; @interface APPNotificationContent : UNMutableNotificationContent
@property (readonly, getter=id) NSNumber* id; - (id) initWithOptions:(NSDictionary*)dict;
@property (readonly, getter=badgeNumber) NSInteger badgeNumber; - (APPNotificationOptions*) options;
@property (readonly, getter=alertBody) NSString* alertBody; - (UNNotificationRequest*) request;
@property (readonly, getter=soundName) NSString* soundName;
@property (readonly, getter=fireDate) NSDate* fireDate;
@property (readonly, getter=repeatInterval) NSCalendarUnit repeatInterval;
@property (readonly, getter=userInfo) NSDictionary* userInfo;
// If it's a repeating notification
- (BOOL) isRepeating;
@end @end
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationContent.h"
#import "APPNotificationOptions.h"
#import "UNUserNotificationCenter+APPLocalNotification.h"
#import <objc/runtime.h>
@import UserNotifications;
static char optionsKey;
@implementation APPNotificationContent : UNMutableNotificationContent
#pragma mark -
#pragma mark Init
/**
* Initialize a notification with the given options.
*
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ UNMutableNotificationContent ]
*/
- (id) initWithOptions:(NSDictionary*)dict
{
self = [self init];
[self setUserInfo:dict];
[self __init];
return self;
}
/**
* Initialize a notification by using the options found under userInfo.
*
* @return [ Void ]
*/
- (void) __init
{
APPNotificationOptions* options = self.options;
self.title = options.title;
self.subtitle = options.subtitle;
self.body = options.text;
self.sound = options.sound;
self.badge = options.badge;
self.attachments = options.attachments;
self.categoryIdentifier = kAPPGeneralCategory;
}
#pragma mark -
#pragma mark Public
/**
* The options used to initialize the notification.
*
* @return [ APPNotificationOptions* ] options
*/
- (APPNotificationOptions*) options
{
APPNotificationOptions* options = [self getOptions];
if (!options) {
options = [[APPNotificationOptions alloc]
initWithDict:[self userInfo]];
[self setOptions:options];
}
return options;
}
/**
* The notifcations request ready to add to the notification center including
* all informations about trigger behavior.
*
* @return [ UNNotificationRequest* ]
*/
- (UNNotificationRequest*) request
{
APPNotificationOptions* opts = [self getOptions];
return [UNNotificationRequest requestWithIdentifier:opts.identifier
content:self
trigger:opts.trigger];
}
#pragma mark -
#pragma mark Private
/**
* The options used to initialize the notification.
*
* @return [ APPNotificationOptions* ]
*/
- (APPNotificationOptions*) getOptions
{
return objc_getAssociatedObject(self, &optionsKey);
}
/**
* Set the options used to initialize the notification.
*
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ Void ]
*/
- (void) setOptions:(APPNotificationOptions*)options
{
objc_setAssociatedObject(self, &optionsKey,
options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
...@@ -21,39 +21,21 @@ ...@@ -21,39 +21,21 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "APPLocalNotificationOptions.ios9.h" @import UserNotifications;
#ifndef APPNotificationType_DEFINED @interface APPNotificationOptions : NSObject
typedef NS_ENUM(NSUInteger, APPNotificationType) {
NotifcationTypeAll = 0,
NotifcationTypeScheduled = 1,
NotifcationTypeTriggered = 2
};
#endif
@interface UILocalNotification (APPLocalNotification) @property (readonly, getter=id) NSNumber* id;
@property (readonly, getter=identifier) NSString* identifier;
@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=sound) UNNotificationSound* sound;
@property (readonly, getter=attachments) NSArray<UNNotificationAttachment *> * attachments;
@property (readonly, getter=userInfo) NSDictionary* userInfo;
// Initialize a new local notification - (id) initWithDict:(NSDictionary*)dict;
- (id) initWithOptions:(NSDictionary*)dict; - (UNNotificationTrigger*) trigger;
// The options provided by the plug-in
- (APPLocalNotificationOptions9*) options;
// Timeinterval since last trigger date
- (double) timeIntervalSinceLastTrigger;
// Timeinterval since fire date
- (double) timeIntervalSinceFireDate;
// If the fire date was in the past
- (BOOL) wasInThePast;
// If the notification was already scheduled
- (BOOL) isScheduled;
// If the notification was already triggered
- (BOOL) isTriggered;
// If the notification was updated
- (BOOL) wasUpdated;
// If it's a repeating notification
- (BOOL) isRepeating;
// Notifciation type
- (APPNotificationType) type;
// Encode the user info dict to JSON
- (NSString*) encodeToJSON;
@end @end
...@@ -21,12 +21,14 @@ ...@@ -21,12 +21,14 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "APPNotificationOptions.h"
@import UserNotifications; @import UserNotifications;
@interface UNNotificationRequest (APPLocalNotification) @interface UNNotificationRequest (APPLocalNotification)
// The options provided by the plug-in // The options provided by the plug-in
- (APPLocalNotificationOptions*) options; - (APPNotificationOptions*) options;
// Encode the user info dict to JSON // Encode the user info dict to JSON
- (NSString*) encodeToJSON; - (NSString*) encodeToJSON;
......
...@@ -21,9 +21,9 @@ ...@@ -21,9 +21,9 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "UNMutableNotificationContent+APPLocalNotification.h" #import "APPNotificationOptions.h"
#import "APPLocalNotificationOptions.h"
#import "UNNotificationRequest+APPLocalNotification.h" #import "UNNotificationRequest+APPLocalNotification.h"
#import "APPNotificationContent.h"
#import <objc/runtime.h> #import <objc/runtime.h>
@import UserNotifications; @import UserNotifications;
...@@ -35,7 +35,7 @@ static char optionsKey; ...@@ -35,7 +35,7 @@ static char optionsKey;
/** /**
* Get associated option object * Get associated option object
*/ */
- (APPLocalNotificationOptions*) getOptions - (APPNotificationOptions*) getOptions
{ {
return objc_getAssociatedObject(self, &optionsKey); return objc_getAssociatedObject(self, &optionsKey);
} }
...@@ -43,7 +43,7 @@ static char optionsKey; ...@@ -43,7 +43,7 @@ static char optionsKey;
/** /**
* Set associated option object * Set associated option object
*/ */
- (void) setOptions:(APPLocalNotificationOptions*)options - (void) setOptions:(APPNotificationOptions*)options
{ {
objc_setAssociatedObject(self, &optionsKey, objc_setAssociatedObject(self, &optionsKey,
options, OBJC_ASSOCIATION_RETAIN_NONATOMIC); options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
...@@ -52,12 +52,12 @@ static char optionsKey; ...@@ -52,12 +52,12 @@ static char optionsKey;
/** /**
* The options provided by the plug-in. * The options provided by the plug-in.
*/ */
- (APPLocalNotificationOptions*) options - (APPNotificationOptions*) options
{ {
APPLocalNotificationOptions* options = [self getOptions]; APPNotificationOptions* options = [self getOptions];
if (!options) { if (!options) {
options = [[APPLocalNotificationOptions alloc] options = [[APPNotificationOptions alloc]
initWithDict:[self.content userInfo]]; initWithDict:[self.content userInfo]];
[self setOptions:options]; [self setOptions:options];
......
...@@ -21,10 +21,12 @@ ...@@ -21,10 +21,12 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "UNMutableNotificationContent+APPLocalNotification.h" #import "APPNotificationContent.h"
@interface UNUserNotificationCenter (APPLocalNotification) @interface UNUserNotificationCenter (APPLocalNotification)
extern NSString * const kAPPGeneralCategory;
typedef NS_ENUM(NSUInteger, APPNotificationType) { typedef NS_ENUM(NSUInteger, APPNotificationType) {
NotifcationTypeAll = 0, NotifcationTypeAll = 0,
NotifcationTypeScheduled = 1, NotifcationTypeScheduled = 1,
...@@ -36,6 +38,8 @@ typedef NS_ENUM(NSUInteger, APPNotificationType) { ...@@ -36,6 +38,8 @@ typedef NS_ENUM(NSUInteger, APPNotificationType) {
@property (readonly, getter=getNotifications) NSArray* localNotifications; @property (readonly, getter=getNotifications) NSArray* localNotifications;
@property (readonly, getter=getNotificationIds) NSArray* localNotificationIds; @property (readonly, getter=getNotificationIds) NSArray* localNotificationIds;
- (void) registerGeneralNotificationCategory;
// List of all notification IDs from given type // List of all notification IDs from given type
- (NSArray*) getNotificationIdsByType:(APPNotificationType)type; - (NSArray*) getNotificationIdsByType:(APPNotificationType)type;
......
...@@ -26,9 +26,32 @@ ...@@ -26,9 +26,32 @@
@import UserNotifications; @import UserNotifications;
NSString * const kAPPGeneralCategory = @"GENERAL";
@implementation UNUserNotificationCenter (APPLocalNotification) @implementation UNUserNotificationCenter (APPLocalNotification)
#pragma mark - #pragma mark -
#pragma mark NotificationCategory
/**
* Register general notification category to listen for dismiss actions.
*
* @return [ Void ]
*/
- (void) registerGeneralNotificationCategory
{
UNNotificationCategory* category;
category = [UNNotificationCategory
categoryWithIdentifier:kAPPGeneralCategory
actions:@[]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
[self setNotificationCategories:[NSSet setWithObjects:category, nil]];
}
#pragma mark -
#pragma mark LocalNotifications #pragma mark LocalNotifications
/** /**
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import <Foundation/Foundation.h>
#import <Cordova/CDVPlugin.h>
@interface APPLocalNotification9 : CDVPlugin
// Execute all queued events
- (void) deviceready:(CDVInvokedUrlCommand*)command;
// Inform if the app has the permission to show notifications
- (void) hasPermission:(CDVInvokedUrlCommand*)command;
// Register permission to show notifications
- (void) registerPermission:(CDVInvokedUrlCommand*)command;
// Schedule set of notifications
- (void) schedule:(CDVInvokedUrlCommand*)command;
// Update set of notifications
- (void) update:(CDVInvokedUrlCommand*)command;
// Cancel set of notifications
- (void) cancel:(CDVInvokedUrlCommand*)command;
// Cancel all notifications
- (void) cancelAll:(CDVInvokedUrlCommand*)command;
// Clear set of notifications
- (void) clear:(CDVInvokedUrlCommand*)command;
// Clear all notifications
- (void) clearAll:(CDVInvokedUrlCommand*)command;
// If a notification with an ID is present
- (void) isPresent:(CDVInvokedUrlCommand*)command;
// If a notification with an ID is scheduled
- (void) isScheduled:(CDVInvokedUrlCommand*)command;
// If a notification with an ID is triggered
- (void) isTriggered:(CDVInvokedUrlCommand*)command;
// List all ids from all local notifications
- (void) getAllIds:(CDVInvokedUrlCommand*)command;
// List all ids from all pending notifications
- (void) getScheduledIds:(CDVInvokedUrlCommand*)command;
// List all ids from all triggered notifications
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command;
// Propertys for given local notification
- (void) getSingle:(CDVInvokedUrlCommand*)command;
// Propertya for given scheduled notification
- (void) getSingleScheduled:(CDVInvokedUrlCommand*)command;
// Propertys for given triggered notification
- (void) getSingleTriggered:(CDVInvokedUrlCommand*)command;
// Property list for given local notifications
- (void) getAll:(CDVInvokedUrlCommand*)command;
// Property list for given scheduled notifications
- (void) getScheduled:(CDVInvokedUrlCommand*)command;
// Property list for given triggered notifications
- (void) getTriggered:(CDVInvokedUrlCommand*)command;
@end
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPLocalNotificationOptions.ios9.h"
@interface APPLocalNotificationOptions9 ()
// The dictionary which contains all notification properties
@property(nonatomic, retain) NSDictionary* dict;
@end
@implementation APPLocalNotificationOptions9
@synthesize dict;
#pragma mark -
#pragma mark Initialization
/**
* Initialize the object with the given options when calling on JS side:
* notification.local.add(options)
*/
- (id) initWithDict:(NSDictionary*)dictionary
{
self = [self init];
self.dict = dictionary;
return self;
}
#pragma mark -
#pragma mark Attributes
/**
* The notification's ID.
*/
- (NSNumber*) id
{
NSInteger id = [[dict objectForKey:@"id"] integerValue];
return [NSNumber numberWithInteger:id];
}
/**
* The notification's title.
*/
- (NSString*) title
{
return [dict objectForKey:@"title"];
}
/**
* The notification's message.
*/
- (NSString*) text
{
return [dict objectForKey:@"text"];
}
/**
* The notification's badge number.
*/
- (NSInteger) badgeNumber
{
return [[dict objectForKey:@"badge"] intValue];
}
#pragma mark -
#pragma mark Complex Attributes
/**
* The notification's alert body.
*/
- (NSString*) alertBody
{
NSString* title = [self title];
NSString* msg = [self text];
NSString* alertBody = msg;
if (![self stringIsNullOrEmpty:title])
{
alertBody = [NSString stringWithFormat:@"%@\n%@",
title, msg];
}
return alertBody;
}
/**
* The notification's sound path.
*/
- (NSString*) soundName
{
NSString* path = [dict objectForKey:@"sound"];
if ([self stringIsNullOrEmpty:path])
return NULL;
if ([path isEqualToString:@"res://platform_default"])
return UILocalNotificationDefaultSoundName;
if ([path hasPrefix:@"file:/"])
return [self soundNameForAsset:path];
if ([path hasPrefix:@"res:"])
return [self soundNameForResource:path];
return NULL;
}
/**
* The notification's fire date.
*/
- (NSDate*) fireDate
{
double timestamp = [[dict objectForKey:@"at"]
doubleValue];
return [NSDate dateWithTimeIntervalSince1970:timestamp];
}
/**
* The notification's repeat interval.
*/
- (NSCalendarUnit) repeatInterval
{
NSString* interval = [dict objectForKey:@"every"];
if ([self stringIsNullOrEmpty:interval]) {
return NSCalendarUnitEra;
}
else if ([interval isEqualToString:@"second"]) {
return NSCalendarUnitSecond;
}
else if ([interval isEqualToString:@"minute"]) {
return NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"hour"]) {
return NSCalendarUnitHour;
}
else if ([interval isEqualToString:@"day"]) {
return NSCalendarUnitDay;
}
else if ([interval isEqualToString:@"week"]) {
return NSCalendarUnitWeekOfYear;
}
else if ([interval isEqualToString:@"month"]) {
return NSCalendarUnitMonth;
}
else if ([interval isEqualToString:@"quarter"]) {
return NSCalendarUnitQuarter;
}
else if ([interval isEqualToString:@"year"]) {
return NSCalendarUnitYear;
}
return NSCalendarUnitEra;
}
#pragma mark -
#pragma mark Methods
/**
* The notification's user info dict.
*/
- (NSDictionary*) userInfo
{
if ([dict objectForKey:@"updatedAt"]) {
NSMutableDictionary* data = [dict mutableCopy];
[data removeObjectForKey:@"updatedAt"];
return data;
}
return dict;
}
/**
* If it's a repeating notification.
*/
- (BOOL) isRepeating
{
NSCalendarUnit interval = self.repeatInterval;
return !(interval == NSCalendarUnitEra || interval == 0);
}
#pragma mark -
#pragma mark Helpers
/**
* Convert relative path to valid sound name attribute.
*/
- (NSString*) soundNameForAsset:(NSString*)path
{
return [path stringByReplacingOccurrencesOfString:@"file:/"
withString:@"www"];
}
/**
* Convert resource path to valid sound name attribute.
*/
- (NSString*) soundNameForResource:(NSString*)path
{
return [path pathComponents].lastObject;
}
/**
* If the string is empty.
*/
- (BOOL) stringIsNullOrEmpty:(NSString*)str
{
if (str == (NSString*)[NSNull null])
return YES;
if ([str isEqualToString:@""])
return YES;
return NO;
}
@end
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "UIApplication+APPLocalNotification.ios9.h"
#import "UILocalNotification+APPLocalNotification.ios9.h"
@implementation UIApplication (APPLocalNotification)
#pragma mark -
#pragma mark Permissions
/**
* If the app has the permission to schedule local notifications.
*/
- (BOOL) hasPermissionToScheduleLocalNotifications
{
if ([[UIApplication sharedApplication]
respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationType types;
UIUserNotificationSettings *settings;
settings = [[UIApplication sharedApplication]
currentUserNotificationSettings];
types = UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound;
return (settings.types & types);
} else {
return YES;
}
}
/**
* Ask for permission to schedule local notifications.
*/
- (void) registerPermissionToScheduleLocalNotifications
{
if ([[UIApplication sharedApplication]
respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationType types;
UIUserNotificationSettings *settings;
settings = [[UIApplication sharedApplication]
currentUserNotificationSettings];
types = settings.types|UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound;
settings = [UIUserNotificationSettings settingsForTypes:types
categories:nil];
[[UIApplication sharedApplication]
registerUserNotificationSettings:settings];
}
}
#pragma mark -
#pragma mark LocalNotifications
/**
* List of all local notifications which have been added
* but not yet removed from the notification center.
*/
- (NSArray*) localNotifications
{
NSArray* scheduledNotifications = self.scheduledLocalNotifications;
NSMutableArray* notifications = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in scheduledNotifications)
{
if (notification) {
[notifications addObject:notification];
}
}
return notifications;
}
/**
* List of all triggered local notifications which have been scheduled
* and not yet removed the notification center.
*/
- (NSArray*) triggeredLocalNotifications
{
NSArray* notifications = self.localNotifications;
NSMutableArray* triggeredNotifications = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
if ([notification isTriggered]) {
[triggeredNotifications addObject:notification];
}
}
return triggeredNotifications;
}
/**
* List of all local notifications IDs.
*/
- (NSArray*) localNotificationIds
{
NSArray* notifications = self.localNotifications;
NSMutableArray* ids = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
[ids addObject:notification.options.id];
}
return ids;
}
/**
* List of all local notifications IDs from given type.
*
* @param type
* Notification life cycle type
*/
- (NSArray*) localNotificationIdsByType:(APPNotificationType)type
{
NSArray* notifications = self.localNotifications;
NSMutableArray* ids = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
if (notification.type == type) {
[ids addObject:notification.options.id];
}
}
return ids;
}
/*
* If local notification with ID exists.
*
* @param id
* Notification ID
*/
- (BOOL) localNotificationExist:(NSNumber*)id
{
return [self localNotificationWithId:id] != NULL;
}
/* If local notification with ID and type exists
*
* @param id
* Notification ID
* @param type
* Notification life cycle type
*/
- (BOOL) localNotificationExist:(NSNumber*)id type:(APPNotificationType)type
{
return [self localNotificationWithId:id andType:type] != NULL;
}
/**
* Get local notification with ID.
*
* @param id
* Notification ID
*/
- (UILocalNotification*) localNotificationWithId:(NSNumber*)id
{
NSArray* notifications = self.localNotifications;
for (UILocalNotification* notification in notifications)
{
NSString* fid = [NSString stringWithFormat:@"%@", notification.options.id];
if ([fid isEqualToString:[id stringValue]]) {
return notification;
}
}
return NULL;
}
/*
* Get local notification with ID and type.
*
* @param id
* Notification ID
* @param type
* Notification life cycle type
*/
- (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPNotificationType)type
{
UILocalNotification* notification = [self localNotificationWithId:id];
if (notification && notification.type == type)
return notification;
return NULL;
}
/**
* List of properties from all notifications.
*/
- (NSArray*) localNotificationOptions
{
NSArray* notifications = self.localNotifications;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
[options addObject:notification.options.userInfo];
}
return options;
}
/**
* List of properties from all local notifications from given type.
*
* @param type
* Notification life cycle type
*/
- (NSArray*) localNotificationOptionsByType:(APPNotificationType)type
{
NSArray* notifications = self.localNotifications;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
if (notification.type == type) {
[options addObject:notification.options.userInfo];
}
}
return options;
}
/**
* List of properties from given local notifications.
*
* @param ids
* Notification IDs
*/
- (NSArray*) localNotificationOptionsById:(NSArray*)ids
{
UILocalNotification* notification;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (NSNumber* id in ids)
{
notification = [self localNotificationWithId:id];
if (notification) {
[options addObject:notification.options.userInfo];
}
}
return options;
}
/**
* List of properties from given local notifications.
*
* @param type
* Notification life cycle type
* @param ids
* Notification IDs
*/
- (NSArray*) localNotificationOptionsByType:(APPNotificationType)type andId:(NSArray*)ids
{
UILocalNotification* notification;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (NSNumber* id in ids)
{
notification = [self localNotificationWithId:id];
if (notification && notification.type == type) {
[options addObject:notification.options.userInfo];
}
}
return options;
}
/*
* Clear all local notfications.
*/
- (void) clearAllLocalNotifications
{
NSArray* notifications = self.triggeredLocalNotifications;
for (UILocalNotification* notification in notifications) {
[self clearLocalNotification:notification];
}
}
/*
* Clear single local notfication.
*
* @param notification
* The local notification object
*/
- (void) clearLocalNotification:(UILocalNotification*)notification
{
[self cancelLocalNotification:notification];
if ([notification isRepeating]) {
notification.fireDate = notification.options.fireDate;
[self scheduleLocalNotification:notification];
};
}
@end
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* 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.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "UILocalNotification+APPLocalNotification.ios9.h"
#import "APPLocalNotificationOptions.ios9.h"
#import <objc/runtime.h>
static char optionsKey;
NSInteger const APPLocalNotificationTypeScheduled = 1;
NSInteger const APPLocalNotificationTypeTriggered = 2;
@implementation UILocalNotification (APPLocalNotification)
#pragma mark -
#pragma mark Init
/**
* Initialize a local notification with the given options when calling on JS side:
* notification.local.add(options)
*/
- (id) initWithOptions:(NSDictionary*)dict
{
self = [self init];
[self setUserInfo:dict];
[self __init];
return self;
}
/**
* Applies the given options when calling on JS side:
* notification.local.add(options)
*/
- (void) __init
{
APPLocalNotificationOptions9* options = self.options;
self.fireDate = options.fireDate;
self.timeZone = [NSTimeZone defaultTimeZone];
self.applicationIconBadgeNumber = options.badgeNumber;
self.repeatInterval = options.repeatInterval;
self.alertBody = options.alertBody;
self.soundName = options.soundName;
if ([self wasInThePast]) {
self.fireDate = [NSDate date];
}
}
#pragma mark -
#pragma mark Methods
/**
* The options provided by the plug-in.
*/
- (APPLocalNotificationOptions9*) options
{
APPLocalNotificationOptions9* options = [self getOptions];
if (!options) {
options = [[APPLocalNotificationOptions9 alloc]
initWithDict:[self userInfo]];
[self setOptions:options];
}
return options;
}
/**
* Get associated option object
*/
- (APPLocalNotificationOptions9*) getOptions
{
return objc_getAssociatedObject(self, &optionsKey);
}
/**
* Set associated option object
*/
- (void) setOptions:(APPLocalNotificationOptions9*)options
{
objc_setAssociatedObject(self, &optionsKey,
options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
/**
* The repeating interval in seconds.
*/
- (int) repeatIntervalInSeconds
{
switch (self.repeatInterval) {
case NSCalendarUnitMinute:
return 60;
case NSCalendarUnitHour:
return 60000;
case NSCalendarUnitDay:
case NSCalendarUnitWeekOfYear:
case NSCalendarUnitMonth:
case NSCalendarUnitYear:
return 86400;
default:
return 1;
}
}
/**
* Timeinterval since fire date.
*/
- (double) timeIntervalSinceFireDate
{
NSDate* now = [NSDate date];
NSDate* fireDate = self.fireDate;
int timespan = [now timeIntervalSinceDate:fireDate];
return timespan;
}
/**
* Timeinterval since last trigger date.
*/
- (double) timeIntervalSinceLastTrigger
{
int timespan = [self timeIntervalSinceFireDate];
if ([self isRepeating]) {
timespan = timespan % [self repeatIntervalInSeconds];
}
return timespan;
}
/**
* Encode the user info dict to JSON.
*/
- (NSString*) encodeToJSON
{
NSString* json;
NSData* data;
NSMutableDictionary* obj = [self.userInfo mutableCopy];
[obj removeObjectForKey:@"updatedAt"];
if (obj == NULL || obj.count == 0)
return json;
data = [NSJSONSerialization dataWithJSONObject:obj
options:NSJSONWritingPrettyPrinted
error:NULL];
json = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
return [json stringByReplacingOccurrencesOfString:@"\n"
withString:@""];
}
#pragma mark -
#pragma mark State
/**
* If the fire date was in the past.
*/
- (BOOL) wasInThePast
{
return [self timeIntervalSinceLastTrigger] > 0;
}
// If the notification was already scheduled
- (BOOL) isScheduled
{
return [self isRepeating] || ![self wasInThePast];
}
/**
* If the notification was already triggered.
*/
- (BOOL) isTriggered
{
NSDate* now = [NSDate date];
NSDate* fireDate = self.fireDate;
bool isLaterThanFireDate = !([now compare:fireDate] == NSOrderedAscending);
return isLaterThanFireDate;
}
/**
* If the notification was updated.
*/
- (BOOL) wasUpdated
{
NSDate* now = [NSDate date];
NSDate* updatedAt = [self.userInfo objectForKey:@"updatedAt"];
if (updatedAt == NULL)
return NO;
int timespan = [now timeIntervalSinceDate:updatedAt];
return timespan < 1;
}
/**
* If it's a repeating notification.
*/
- (BOOL) isRepeating
{
return [self.options isRepeating];
}
/**
* Process state type of the local notification.
*/
- (APPNotificationType) type
{
return [self isTriggered] ? NotifcationTypeTriggered : NotifcationTypeScheduled;
}
@end
/* /*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code * This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License * as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in * Version 2.0 (the 'License'). You may not use this file except in
...@@ -17,18 +13,11 @@ ...@@ -17,18 +13,11 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and * Please see the License for the specific language governing rights and
* limitations under the License. * limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/ */
var exec = require('cordova/exec'), var exec = require('cordova/exec'),
channel = require('cordova/channel'); channel = require('cordova/channel');
/***********
* MEMBERS *
***********/
// Default values // Default values
exports._defaults = { exports._defaults = {
text: '', text: '',
...@@ -41,22 +30,13 @@ exports._defaults = { ...@@ -41,22 +30,13 @@ exports._defaults = {
at: undefined at: undefined
}; };
// listener // Listener
exports._listener = {}; exports._listener = {};
// Registered permission flag
exports._registered = false;
/********
* UTIL *
********/
/** /**
* Merge platform specific properties into the default ones. * Merge platform specific properties into the default ones.
* *
* @return {Object} * @return [ Void ]
* The default properties for the platform
*/ */
exports.applyPlatformSpecificOptions = function () { exports.applyPlatformSpecificOptions = function () {
var defaults = this._defaults; var defaults = this._defaults;
...@@ -70,19 +50,18 @@ exports.applyPlatformSpecificOptions = function () { ...@@ -70,19 +50,18 @@ exports.applyPlatformSpecificOptions = function () {
defaults.led = undefined; defaults.led = undefined;
defaults.color = undefined; defaults.color = undefined;
break; break;
case 'iOS':
defaults.attachments = undefined;
break;
} }
return defaults;
}; };
/** /**
* Merge custom properties with the default values. * Merge custom properties with the default values.
* *
* @param {Object} options * @param [ Object ] options Set of custom values.
* Set of custom values
* *
* @retrun {Object} * @retrun [ Object ]
* The merged property list
*/ */
exports.mergeWithDefaults = function (options) { exports.mergeWithDefaults = function (options) {
var defaults = this.getDefaults(); var defaults = this.getDefaults();
...@@ -126,11 +105,9 @@ exports.mergeWithDefaults = function (options) { ...@@ -126,11 +105,9 @@ exports.mergeWithDefaults = function (options) {
/** /**
* Convert the passed values to their required type. * Convert the passed values to their required type.
* *
* @param {Object} options * @param [ Object ] options Properties to convert for.
* Set of custom values
* *
* @retrun {Object} * @return [ Object ] The converted property list
* The converted property list
*/ */
exports.convertProperties = function (options) { exports.convertProperties = function (options) {
...@@ -172,46 +149,33 @@ exports.convertProperties = function (options) { ...@@ -172,46 +149,33 @@ exports.convertProperties = function (options) {
options.data = JSON.stringify(options.data); options.data = JSON.stringify(options.data);
} }
if (options.every) {
if (device.platform == 'iOS' && typeof options.every != 'string') {
options.every = this.getDefaults().every;
var warning = 'Every option is not a string: ' + options.id;
warning += '. Expects one of: second, minute, hour, day, week, ';
warning += 'month, year on iOS.';
console.warn(warning);
}
}
return options; return options;
}; };
/** /**
* Create callback, which will be executed within a specific scope. * Create a callback function to get executed within a specific scope.
* *
* @param {Function} callbackFn * @param [ Function ] fn The function to be exec as the callback.
* The callback function * @param [ Object ] scope The callback function's scope.
* @param {Object} scope
* The scope for the function
* *
* @return {Function} * @return [ Function ]
* The new callback function
*/ */
exports.createCallbackFn = function (callbackFn, scope) { exports.createCallbackFn = function (fn, scope) {
if (typeof callbackFn != 'function') if (typeof fn != 'function')
return; return;
return function () { return function () {
callbackFn.apply(scope || this, arguments); fn.apply(scope || this, arguments);
}; };
}; };
/** /**
* Convert the IDs to numbers. * Convert the IDs to numbers.
* *
* @param {String/Number[]} ids * @param [ Array ] ids
* *
* @return Array of Numbers * @return [ Array<Number> ]
*/ */
exports.convertIds = function (ids) { exports.convertIds = function (ids) {
var convertedIds = []; var convertedIds = [];
...@@ -226,10 +190,10 @@ exports.convertIds = function (ids) { ...@@ -226,10 +190,10 @@ exports.convertIds = function (ids) {
/** /**
* First found value for the given keys. * First found value for the given keys.
* *
* @param {Object} options * @param [ Object ] options Object with key-value properties.
* Object with key-value properties * @param [ *Array<String> ] keys List of keys.
* @param {String[]} keys* *
* Key list * @return [ Object ]
*/ */
exports.getValueFor = function (options) { exports.getValueFor = function (options) {
var keys = Array.apply(null, arguments).slice(1); var keys = Array.apply(null, arguments).slice(1);
...@@ -244,12 +208,12 @@ exports.getValueFor = function (options) { ...@@ -244,12 +208,12 @@ exports.getValueFor = function (options) {
}; };
/** /**
* Fire event with given arguments. * Fire the event with given arguments.
* *
* @param {String} event * @param [ String ] event The event's name.
* The event's name * @param [ *Array] args The callback's arguments.
* @param {args*} *
* The callback's arguments * @return [ Void]
*/ */
exports.fireEvent = function (event) { exports.fireEvent = function (event) {
var args = Array.apply(null, arguments).slice(1), var args = Array.apply(null, arguments).slice(1),
...@@ -269,14 +233,12 @@ exports.fireEvent = function (event) { ...@@ -269,14 +233,12 @@ exports.fireEvent = function (event) {
/** /**
* Execute the native counterpart. * Execute the native counterpart.
* *
* @param {String} action * @param [ String ] action The name of the action.
* The name of the action * @param [ Array ] args Array of arguments.
* @param args[] * @param [ Function] callback The callback function.
* Array of arguments * @param [ Object ] scope The scope for the function.
* @param {Function} callback *
* The callback function * @return [ Void ]
* @param {Object} scope
* The scope for the function
*/ */
exports.exec = function (action, args, callback, scope) { exports.exec = function (action, args, callback, scope) {
var fn = this.createCallbackFn(callback, scope), var fn = this.createCallbackFn(callback, scope),
...@@ -291,11 +253,6 @@ exports.exec = function (action, args, callback, scope) { ...@@ -291,11 +253,6 @@ exports.exec = function (action, args, callback, scope) {
exec(fn, null, 'LocalNotification', action, params); exec(fn, null, 'LocalNotification', action, params);
}; };
/*********
* HOOKS *
*********/
// Called after 'deviceready' event // Called after 'deviceready' event
channel.deviceready.subscribe(function () { channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered // Device is ready now, the listeners are registered
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<body> <body>
<div> <div>
<div class="app"> <div class="app">
<h1>Local Notification Example</h1> <h1>Notification Example</h1>
<div id="deviceready" class="blink"> <div id="deviceready" class="blink">
<p class="event listening">Connecting to Device</p> <p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p> <p class="event received">Device is Ready</p>
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
<a id="sched_multi" class="button orange">Multiple</a> <a id="sched_multi" class="button orange">Multiple</a>
</div> </div>
<div class="container"> <div class="container">
<a id="sched_delay" class="button orange">Delayed</a> <a id="sched_delayed" class="button orange">Delayed</a>
<a id="sched_interval" class="button orange">Interval</a> <a id="sched_interval" class="button orange">Interval</a>
</div> </div>
<h2 class="section">Update</h2> <h2 class="section">Update</h2>
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
<a id="triggered_ids" class="button grey">Triggered</a> <a id="triggered_ids" class="button grey">Triggered</a>
</div> </div>
<div class="container"> <div class="container">
<a id="all_ids" class="button grey">All</a> <a id="ids" class="button grey">All</a>
</div> </div>
<h2 class="section">Notifications</h2> <h2 class="section">Notifications</h2>
<div class="container"> <div class="container">
...@@ -93,11 +93,11 @@ ...@@ -93,11 +93,11 @@
<a id="triggered_nots" class="button grey">Triggered</a> <a id="triggered_nots" class="button grey">Triggered</a>
</div> </div>
<div class="container"> <div class="container">
<a id="single_not" class="button grey">Single</a> <a id="notification" class="button grey">Single</a>
<a id="multiple_nots" class="button grey">Multiple</a> <a id="multiple_nots" class="button grey">Multiple</a>
</div> </div>
<div class="container"> <div class="container">
<a id="all_nots" class="button grey">All</a> <a id="notifications" class="button grey">All</a>
</div> </div>
<h2 class="section">Defaults</h2> <h2 class="section">Defaults</h2>
<div class="container"> <div class="container">
......
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