Skip to content
This repository was archived by the owner on Feb 7, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions definitions.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
export declare interface IosInteractiveNotificationAction {
identifier: string;
title: string;
activationMode?: string;
destructive?: boolean;
authenticationRequired?: boolean;
behavior?: string;
}

export declare interface IosInteractiveNotificationCategory {
identifier: string;
actionsForDefaultContext: string[];
actionsForMinimalContext: string[];
}

export declare interface IosRegistrationOptions {
badge: boolean;
sound: boolean;
alert: boolean;
clearBadge: boolean;
interactiveSettings: {
actions: IosInteractiveNotificationAction[],
categories: IosInteractiveNotificationCategory[]
},
notificationCallbackIOS: (message: string) => void;
}

export declare interface NSError {
code: number;
domain: string;
userInfo: any
}

export declare interface FcmNotificaion {
getBody(): string;
getBodyLocalizationArgs(): string[];
getBodyLocalizationKey(): string;
getClickAction(): string;
getColor(): string;
getIcon(): string;
getSound(): string;
getTag(): string;
getTitle(): string;
getTitleLocalizationArgs(): string[];
getTitleLocalizationKey(): string;
}

// Common
export declare function register(options: IosRegistrationOptions, successCallback: (token: string) => void, errorCallback: (error: NSError) => void): void;
export declare function register(options: { senderID: string }, successCallback: (fcmRegistrationToken: string) => void, errorCallback: (errorMessage: string) => void): void;
export declare function unregister(successCallback: (successMessage: string) => void): void; // iOS
export declare function unregister(successCallback: (successMessage: string) => void, errorCallback: (errorMessage: string) => void, options: { senderID: string }): void;
export declare function areNotificationsEnabled(callback: (boolean) => void): void;

// Android only
export declare function onMessageReceived(callback: (message: string, stringifiedData: string, fcmNotification: FcmNotificaion) => void): void;
export declare function onTokenRefresh(callback: () => void): void;

// iOS only
export declare function registerUserNotificationSettings(successCallback: () => void, errorCallback: (error: NSError) => void): void;
18 changes: 18 additions & 0 deletions hooks/before-prepare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var utils = require('./utils');

module.exports = function ($logger, $projectData) {

// No need to check if file exists cause it's a before-prepare hook
// and if project targets Android, platforms dir is already created.
// If Android is not set up correctly, platform is not added and we log an error

utils.setLogger(_log);

if (utils.targetsAndroid($projectData.projectDir)) {
utils.addIfNecessary($projectData.platformsDir);
}

function _log (str) {
$logger.info('nativescript-push-notifications -- ' + str);
}
};
159 changes: 159 additions & 0 deletions hooks/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
var path = require('path');
var fs = require('fs');
var os = require('os');

var PLUGIN_VERSION = '+';
var _log = console.log.bind(console);

function targetsAndroid (projectDir) {
var pkg = require(path.join(projectDir, 'package.json'));
if (!pkg.nativescript) {
throw new Error('Not a NativeScript project');
}

return ('tns-android' in pkg.nativescript);
}

function buildGradleExists (platformsDir) {
return fs.existsSync(_getBuildGradlePath(platformsDir));
}

function checkForGoogleServicesJson (projectDir, resourcesDir) {
var androidIsTargeted = targetsAndroid(projectDir);
var resourcesPath = path.join(resourcesDir, 'Android', 'google-services.json');

if (androidIsTargeted && !fs.existsSync(resourcesPath)) {
_log('|!| google-services.json appears to be missing. Please make sure it is present in the "app/App_Resources/Android" folder, in order to use FCM push notifications |!|');
}
}

function addOnPluginInstall (platformsDir) {
var path = _getBuildGradlePath(platformsDir);
if (buildGradleExists(platformsDir)) {
addIfNecessary(platformsDir);
}
}

function addIfNecessary (platformsDir) {
_amendBuildGradle(platformsDir, function (pluginImported, pluginApplied, fileContents) {
var newContents = fileContents;
if (!pluginImported) {
newContents = _addPluginImport(newContents);
}

if (!pluginApplied) {
newContents = _addPluginApplication(newContents);
}
return newContents;
});
}

function removeIfPresent (platformsDir) {
_amendBuildGradle(platformsDir, function (pluginImported, pluginApplied, fileContents) {
var newFileContents = fileContents;
if (pluginImported) {
newFileContents = _removePluginImport(newFileContents);
}

if (pluginApplied) {
newFileContents = _removePluginApplication(newFileContents);
}
return newFileContents;
});
}

function setLogger (logFunc) {
_log = logFunc;
}

// ============= private

var _quotesRegExp = '["\']';
var _versionRegExp = '[^\'"]+';
var _pluginImportName = 'com.google.gms:google-services';
var _pluginApplicationName = 'com.google.gms.google-services';

function _amendBuildGradle (platformsDir, applyAmendment) {
var path = _getBuildGradlePath(platformsDir);

if (!buildGradleExists(platformsDir)) {
return _log('build.gradle file not found');
}

var fileContents = fs.readFileSync(path, 'utf8');
var pluginImported = _checkForImport(fileContents);
var pluginApplied = _checkForApplication(fileContents);
var newContents = applyAmendment(pluginImported, pluginApplied, fileContents);

fs.writeFileSync(path, newContents, 'utf8');
}

function _removePluginImport (buildGradleContents) {
var regExpStr = '\\s*classpath +' + _formNamePartOfRegExp(true) + '{0,0}:' + _versionRegExp + _quotesRegExp;
var regExp = new RegExp(regExpStr, 'i');
return buildGradleContents.replace(regExp, '');
}

function _removePluginApplication (buildGradleContents) {
var regExpStr = '\\s*apply plugin: +' + _formNamePartOfRegExp(false);
var regExp = new RegExp(regExpStr, 'i');
return buildGradleContents.replace(regExp, '');
}

function _addPluginImport (buildGradleContents) {
var androidGradle = 'com.android.tools.build:gradle';
var insertBeforeDoubleQuotes = 'classpath "' + androidGradle;
var insertBeforeSingleQoutes = 'classpath \'' + androidGradle;

var ind = buildGradleContents.indexOf(insertBeforeDoubleQuotes);
if (ind === -1) {
ind = buildGradleContents.indexOf(insertBeforeSingleQoutes);
}

if (ind === -1) {
_log('build.gradle has unexpected contents -- please check it manually');
return buildGradleContents;
}

var result = buildGradleContents.substring(0, ind);
result += 'classpath "' + _pluginImportName + ':' + PLUGIN_VERSION + '"' + os.EOL;
result += '\t\t' + insertBeforeDoubleQuotes;
result += buildGradleContents.substring(ind + ('classpath "' + androidGradle).length);
return result;
}

function _addPluginApplication (buildGradleContents) {
buildGradleContents += os.EOL + 'apply plugin: "' + _pluginApplicationName + '"' + os.EOL;
return buildGradleContents;
}

function _formNamePartOfRegExp (useImportName) {
var name = useImportName ? _pluginImportName : _pluginApplicationName;
return _quotesRegExp + name + _quotesRegExp;
}

function _checkForImport (buildGradleContents) {
var re = new RegExp('classpath +' + _formNamePartOfRegExp(true) + '{0,0}', 'i');
return re.test(buildGradleContents);
}

function _checkForApplication (buildGradleContents) {
var re = new RegExp('apply plugin: +' + _formNamePartOfRegExp(false), 'i');
return re.test(buildGradleContents);
}

function _getBuildGradlePath (platformsDir) {
return path.join(platformsDir, 'android', 'build.gradle');
}

// ============= end private

module.exports = {
removeIfPresent: removeIfPresent,
setLogger: setLogger,
addIfNecessary: addIfNecessary,
targetsAndroid: targetsAndroid,
buildGradleExists: buildGradleExists,
addOnPluginInstall: addOnPluginInstall,
checkForGoogleServicesJson: checkForGoogleServicesJson
};
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void onActivityPaused(Activity activity) {
}

public void onActivityResumed(Activity activity) {
Log.d(PushPlugin.TAG, "onActivityPaused: Application has been started");
Log.d(PushPlugin.TAG, "onActivityResumed: Application has been started");

// the application has been resumed-> the push plugin is now in active/foreground state
PushPlugin.isActive = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ private static JsonObjectExtended convertMapToJson(Map<String, String> data) {
for (String key: data.keySet()) {
json.put(key, JsonObjectExtended.wrap(data.get(key)));
}
json.put("foreground", PushPlugin.isActive);
} catch (JSONException ex) {
Log.d(TAG, "Error thrown while parsing push notification data bundle to json: " + ex.getMessage());
}
Expand Down
19 changes: 17 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
"platforms": {
"ios": "2.4.0",
"android": "2.4.1"
}
}
},
"hooks": [
{
"type": "before-prepare",
"script": "hooks/before-prepare.js",
"inject": true
}
]
},
"scripts": {
"postinstall": "node postinstall.js",
"preuninstall": "node preuninstall.js"
},
"dependencies": {
"nativescript-hook": "0.2.1"
},
"typings": "./definitions.d.ts"
}
Binary file modified platforms/android/pushplugin.aar
Binary file not shown.
7 changes: 7 additions & 0 deletions postinstall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require('nativescript-hook')(__dirname).postinstall();
var path = require('path');
var utils = require('./hooks/utils');
var projDir = path.resolve(__dirname, '../../');

utils.checkForGoogleServicesJson(projDir, path.join(projDir, 'app', 'App_Resources'));
utils.addOnPluginInstall(path.join(projDir, 'platforms'));
6 changes: 6 additions & 0 deletions preuninstall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require('nativescript-hook')(__dirname).preuninstall();
var path = require('path');
var utils = require('./hooks/utils');
var platformsDir = path.resolve(__dirname, '../../platforms');

utils.removeIfPresent(platformsDir);
14 changes: 9 additions & 5 deletions push-plugin.android.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
module.exports = (function () {
var app = require('application');

(function() {
// Hook on the application events
var registerLifecycleEvents = function () {
com.telerik.pushplugin.PushLifecycleCallbacks.registerCallbacks(app.android.nativeApp);
})();
};

// Hook on the application events
if (app.android.nativeApp) {
registerLifecycleEvents();
} else {
app.on(app.launchEvent, registerLifecycleEvents);
}

var pluginObject = {
register: function (options, successCallback, errorCallback) {
com.telerik.pushplugin.PushPlugin.register(app.android.context, options.senderID,
//Success
new com.telerik.pushplugin.PushPluginListener(
{
success: successCallback,
Expand Down