Skip to content
This repository has been archived by the owner on Sep 4, 2020. It is now read-only.

Commit

Permalink
🐧 πŸ“ Issue #1980: Remove confusing action button syntax and replace wi… (
Browse files Browse the repository at this point in the history
#1981)

* 🐧 πŸ“ Issue #1980: Remove confusing action button syntax and replace with events
  • Loading branch information
macdonst authored Sep 29, 2017
1 parent 8d0ad41 commit 0cb03db
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 87 deletions.
48 changes: 33 additions & 15 deletions docs/PAYLOAD.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,25 @@ If you use `%n%` in the `summaryText` of the JSON coming down from GCM it will b

## Action Buttons

Your notification can include a maximum of three action buttons. If you wish to include an icon along with the button name they must be placed in the `res/drawable` directory of your Android project. Then you can send the following JSON from GCM:
Your notification can include a maximum of three action buttons. You register event listeners with the name of your actions. Then when a user clicks on one of the action buttons that event is fired and the listener you have registered is invoked. For instance here is a setup with two actions `emailGuests` and `snooze`.

```javascript
var push = PushNotification.init({
"android": {
}
});

// data contains the push payload just like a notification event
push.on('emailGuests', function(data) {
console.log('I should email my guests');
});

push.on('snooze', function(data) {
console.log('Remind me later');
});
```

If you wish to include an icon along with the button name they must be placed in the `res/drawable` directory of your Android project. Then you can send the following JSON from GCM:

```javascript
{
Expand All @@ -785,8 +803,8 @@ Your notification can include a maximum of three action buttons. If you wish to
"title": "AUX Scrum",
"message": "Scrum: Daily touchbase @ 10am Please be on time so we can cover everything on the agenda.",
"actions": [
{ "icon": "emailGuests", "title": "EMAIL GUESTS", "callback": "app.emailGuests", "foreground": true},
{ "icon": "snooze", "title": "SNOOZE", "callback": "app.snooze", "foreground": false}
{ "icon": "emailGuests", "title": "EMAIL GUESTS", "callback": "emailGuests", "foreground": true},
{ "icon": "snooze", "title": "SNOOZE", "callback": "snooze", "foreground": false}
]
}
}
Expand All @@ -807,8 +825,8 @@ var message = {
title: 'AUX Scrum',
message: 'Scrum: Daily touchbase @ 10am Please be on time so we can cover everything on the agenda.',
actions: [
{ icon: "emailGuests", title: "EMAIL GUESTS", callback: "app.emailGuests", foreground: true},
{ icon: "snooze", title: "SNOOZE", callback: "app.snooze", foreground: false},
{ icon: "emailGuests", title: "EMAIL GUESTS", callback: "emailGuests", foreground: true},
{ icon: "snooze", title: "SNOOZE", callback: "snooze", foreground: false},
]
}
};
Expand All @@ -827,7 +845,7 @@ This will produce the following notification in your tray:

![action_combo](https://cloud.githubusercontent.com/assets/353180/9313435/02554d2a-44f1-11e5-8cd9-0aadd1e02b18.png)

If your user clicks on the main body of the notification your app will be opened. However if they click on either of the action buttons the app will open (or start) and the specified JavaScript callback will be executed if there is a function defined, and if there isn't an event will be emitted with the callback name. In this case it is `app.emailGuests` and `app.snooze` respectively. If you set the `foreground` property to `true` the app will be brought to the front, if `foreground` is `false` then the callback is run without the app being brought to the foreground.
If your user clicks on the main body of the notification your app will be opened. However if they click on either of the action buttons the app will open (or start) and the specified event will be emitted with the callback name. In this case it is `emailGuests` and `snooze` respectively. If you set the `foreground` property to `true` the app will be brought to the front, if `foreground` is `false` then the callback is run without the app being brought to the foreground.

### In Line Replies

Expand All @@ -842,8 +860,8 @@ Your notification can include action buttons. If you wish to include an icon alo
"title": "AUX Scrum",
"message": "Scrum: Daily touchbase @ 10am Please be on time so we can cover everything on the agenda.",
"actions": [
{ "icon": "emailGuests", "title": "EMAIL GUESTS", "callback": "app.emailGuests", "foreground": false, "inline": true },
{ "icon": "snooze", "title": "SNOOZE", "callback": "app.snooze", "foreground": false}
{ "icon": "emailGuests", "title": "EMAIL GUESTS", "callback": "emailGuests", "foreground": false, "inline": true },
{ "icon": "snooze", "title": "SNOOZE", "callback": "snooze", "foreground": false}
]
}
}
Expand All @@ -864,8 +882,8 @@ var message = {
title: 'AUX Scrum',
message: 'Scrum: Daily touchbase @ 10am Please be on time so we can cover everything on the agenda.',
actions: [
{ "icon": "emailGuests", "title": "EMAIL GUESTS", "callback": "app.emailGuests", "foreground": false, "inline": true},
{ "icon": "snooze", "title": "SNOOZE", "callback": "app.snooze", "foreground": false},
{ "icon": "emailGuests", "title": "EMAIL GUESTS", "callback": "emailGuests", "foreground": false, "inline": true},
{ "icon": "snooze", "title": "SNOOZE", "callback": "snooze", "foreground": false},
]
}
};
Expand Down Expand Up @@ -895,18 +913,18 @@ Then your app's `on('notification')` event handler will be called without the ap
"actions": [
{
"inline": true,
"callback": "app.accept",
"callback": "accept",
"foreground": false,
"title": "Accept"
},
{
"icon": "snooze",
"callback": "app.reject",
"callback": "reject",
"foreground": false,
"title": "Reject"
}
],
"actionCallback": "app.accept",
"actionCallback": "accept",
"coldstart": false,
"collapse_key": "do_not_collapse",
"foreground": false
Expand All @@ -924,7 +942,7 @@ Attribute | Type | Default | Description
--------- | ---- | ------- | -----------
`icon` | `string` | | Optional. The name of a drawable resource to use as the small-icon. The name should not include the extension.
`title` | `string` | | Required. The label to display for the action button.
`callback` | `string` | | Required. The function to be executed or the event to be emitted when the action button is pressed. The function must be accessible from the global namespace. If you provide `myCallback` then it amounts to calling `window.myCallback`. If you provide `app.myCallback` then there needs to be an object call `app`, with a function called `myCallback` accessible from the global namespace, i.e. `window.app.myCallback`. If there isn't a function with the specified name an event will be emitted with the callback name.
`callback` | `string` | | Required. The event to be emitted when the action button is pressed.
`foreground` | `boolean` | `true` | Optional. Whether or not to bring the app to the foreground when the action button is pressed.
`inline` | `boolean` | `false` | Optional. Whether or not to provide a quick reply text field to the user when the button is clicked.

Expand Down Expand Up @@ -1466,7 +1484,7 @@ Android O introduces a new wrinkle to push notifications in the form of Notifica

For instance if you register for push notifications like normal:

```
```javascript
var push = PushNotification.init({
"android": {
}
Expand Down
91 changes: 46 additions & 45 deletions src/js/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,23 @@ class PushNotification {
this.options = options;

// triggered on registration and notification
const success = (result) => {
const success = result => {
if (result && typeof result.registrationId !== 'undefined') {
this.emit('registration', result);
} else if (result && result.additionalData &&
typeof result.additionalData.actionCallback !== 'undefined') {
const executeFuctionOrEmitEventByName = (functionName, context, ...args) => {
const namespaces = functionName.split('.');
const func = namespaces.pop();
let innerContext = context;
for (let i = 0; i < namespaces.length; i++) {
innerContext = innerContext[namespaces[i]];
}

if (typeof innerContext[func] === 'function') {
innerContext[func].call(innerContext, args);
} else {
this.emit(functionName, args);
}
};

executeFuctionOrEmitEventByName(result.additionalData.actionCallback, window, result);
} else if (
result &&
result.additionalData &&
typeof result.additionalData.actionCallback !== 'undefined'
) {
this.emit(result.additionalData.actionCallback, result);
} else if (result) {
this.emit('notification', result);
}
};

// triggered on error
const fail = (msg) => {
const e = (typeof msg === 'string') ? new Error(msg) : msg;
const fail = msg => {
const e = typeof msg === 'string' ? new Error(msg) : msg;
this.emit('error', e);
};

Expand All @@ -78,8 +66,9 @@ class PushNotification {
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.unregister failure: success callback parameter ' +
' must be a function');
console.log(
'PushNotification.unregister failure: success callback parameter must be a function'
);
return;
}

Expand All @@ -106,14 +95,14 @@ class PushNotification {
*/
subscribe(topic, successCallback, errorCallback = () => {}) {
if (typeof errorCallback !== 'function') {
console.log('PushNotification.subscribe failure: ' +
'failure parameter not a function');
console.log('PushNotification.subscribe failure: failure parameter not a function');
return;
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.subscribe failure: ' +
'success callback parameter must be a function');
console.log(
'PushNotification.subscribe failure: success callback parameter must be a function'
);
return;
}

Expand All @@ -134,33 +123,38 @@ class PushNotification {
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.unsubscribe failure: ' +
'success callback parameter must be a function');
console.log(
'PushNotification.unsubscribe failure: success callback parameter must be a function'
);
return;
}

exec(successCallback, errorCallback, 'PushNotification', 'unsubscribe', [topic]);
}


/**
* Call this to set the application icon badge
*/
setApplicationIconBadgeNumber(successCallback, errorCallback = () => {}, badge) {
if (typeof errorCallback !== 'function') {
console.log('PushNotification.setApplicationIconBadgeNumber failure: failure ' +
'parameter not a function');
console.log(
'PushNotification.setApplicationIconBadgeNumber failure: failure ' +
'parameter not a function'
);
return;
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.setApplicationIconBadgeNumber failure: success ' +
'callback parameter must be a function');
console.log(
'PushNotification.setApplicationIconBadgeNumber failure: success ' +
'callback parameter must be a function'
);
return;
}

exec(successCallback, errorCallback, 'PushNotification',
'setApplicationIconBadgeNumber', [{ badge }]);
exec(successCallback, errorCallback, 'PushNotification', 'setApplicationIconBadgeNumber', [
{ badge },
]);
}

/**
Expand All @@ -169,14 +163,18 @@ class PushNotification {

getApplicationIconBadgeNumber(successCallback, errorCallback = () => {}) {
if (typeof errorCallback !== 'function') {
console.log('PushNotification.getApplicationIconBadgeNumber failure: failure ' +
'parameter not a function');
console.log(
'PushNotification.getApplicationIconBadgeNumber failure: failure ' +
'parameter not a function'
);
return;
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.getApplicationIconBadgeNumber failure: success ' +
'callback parameter must be a function');
console.log(
'PushNotification.getApplicationIconBadgeNumber failure: success ' +
'callback parameter must be a function'
);
return;
}

Expand All @@ -189,14 +187,17 @@ class PushNotification {

clearAllNotifications(successCallback = () => {}, errorCallback = () => {}) {
if (typeof errorCallback !== 'function') {
console.log('PushNotification.clearAllNotifications failure: failure parameter ' +
'not a function');
console.log(
'PushNotification.clearAllNotifications failure: failure parameter not a function'
);
return;
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.clearAllNotifications failure: success callback ' +
'parameter must be a function');
console.log(
'PushNotification.clearAllNotifications failure: success callback ' +
'parameter must be a function'
);
return;
}

Expand Down Expand Up @@ -298,7 +299,7 @@ module.exports = {
* @return {PushNotification} instance
*/

init: (options) => new PushNotification(options),
init: options => new PushNotification(options),

hasPermission: (successCallback, errorCallback) => {
exec(successCallback, errorCallback, 'PushNotification', 'hasPermission', []);
Expand Down
35 changes: 8 additions & 27 deletions www/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,7 @@ var PushNotification = function () {
if (result && typeof result.registrationId !== 'undefined') {
_this.emit('registration', result);
} else if (result && result.additionalData && typeof result.additionalData.actionCallback !== 'undefined') {
var executeFuctionOrEmitEventByName = function executeFuctionOrEmitEventByName(functionName, context) {
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}

var namespaces = functionName.split('.');
var func = namespaces.pop();
var innerContext = context;
for (var i = 0; i < namespaces.length; i++) {
innerContext = innerContext[namespaces[i]];
}

if (typeof innerContext[func] === 'function') {
innerContext[func].call(innerContext, args);
} else {
_this.emit(functionName, args);
}
};

executeFuctionOrEmitEventByName(result.additionalData.actionCallback, window, result);
_this.emit(result.additionalData.actionCallback, result);
} else if (result) {
_this.emit('notification', result);
}
Expand Down Expand Up @@ -106,7 +87,7 @@ var PushNotification = function () {
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.unregister failure: success callback parameter ' + ' must be a function');
console.log('PushNotification.unregister failure: success callback parameter must be a function');
return;
}

Expand Down Expand Up @@ -138,12 +119,12 @@ var PushNotification = function () {
var errorCallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};

if (typeof errorCallback !== 'function') {
console.log('PushNotification.subscribe failure: ' + 'failure parameter not a function');
console.log('PushNotification.subscribe failure: failure parameter not a function');
return;
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.subscribe failure: ' + 'success callback parameter must be a function');
console.log('PushNotification.subscribe failure: success callback parameter must be a function');
return;
}

Expand All @@ -169,7 +150,7 @@ var PushNotification = function () {
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.unsubscribe failure: ' + 'success callback parameter must be a function');
console.log('PushNotification.unsubscribe failure: success callback parameter must be a function');
return;
}

Expand Down Expand Up @@ -232,7 +213,7 @@ var PushNotification = function () {
var errorCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};

if (typeof errorCallback !== 'function') {
console.log('PushNotification.clearAllNotifications failure: failure parameter ' + 'not a function');
console.log('PushNotification.clearAllNotifications failure: failure parameter not a function');
return;
}

Expand Down Expand Up @@ -297,8 +278,8 @@ var PushNotification = function () {
}, {
key: 'emit',
value: function emit() {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}

var eventName = args.shift();
Expand Down

0 comments on commit 0cb03db

Please sign in to comment.