Skip to content
This repository was archived by the owner on Feb 7, 2019. It is now read-only.

Commit e12bc20

Browse files
authored
Merge pull request #92 from georgiwe/feature/improvements
Feature/improvements
2 parents 2767500 + ee7f7dd commit e12bc20

File tree

10 files changed

+278
-8
lines changed

10 files changed

+278
-8
lines changed

definitions.d.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
export declare interface IosInteractiveNotificationAction {
2+
identifier: string;
3+
title: string;
4+
activationMode?: string;
5+
destructive?: boolean;
6+
authenticationRequired?: boolean;
7+
behavior?: string;
8+
}
9+
10+
export declare interface IosInteractiveNotificationCategory {
11+
identifier: string;
12+
actionsForDefaultContext: string[];
13+
actionsForMinimalContext: string[];
14+
}
15+
16+
export declare interface IosRegistrationOptions {
17+
badge: boolean;
18+
sound: boolean;
19+
alert: boolean;
20+
clearBadge: boolean;
21+
interactiveSettings: {
22+
actions: IosInteractiveNotificationAction[],
23+
categories: IosInteractiveNotificationCategory[]
24+
},
25+
notificationCallbackIOS: (message: string) => void;
26+
}
27+
28+
export declare interface NSError {
29+
code: number;
30+
domain: string;
31+
userInfo: any
32+
}
33+
34+
export declare interface FcmNotificaion {
35+
getBody(): string;
36+
getBodyLocalizationArgs(): string[];
37+
getBodyLocalizationKey(): string;
38+
getClickAction(): string;
39+
getColor(): string;
40+
getIcon(): string;
41+
getSound(): string;
42+
getTag(): string;
43+
getTitle(): string;
44+
getTitleLocalizationArgs(): string[];
45+
getTitleLocalizationKey(): string;
46+
}
47+
48+
// Common
49+
export declare function register(options: IosRegistrationOptions, successCallback: (token: string) => void, errorCallback: (error: NSError) => void): void;
50+
export declare function register(options: { senderID: string }, successCallback: (fcmRegistrationToken: string) => void, errorCallback: (errorMessage: string) => void): void;
51+
export declare function unregister(successCallback: (successMessage: string) => void): void; // iOS
52+
export declare function unregister(successCallback: (successMessage: string) => void, errorCallback: (errorMessage: string) => void, options: { senderID: string }): void;
53+
export declare function areNotificationsEnabled(callback: (boolean) => void): void;
54+
55+
// Android only
56+
export declare function onMessageReceived(callback: (message: string, stringifiedData: string, fcmNotification: FcmNotificaion) => void): void;
57+
export declare function onTokenRefresh(callback: () => void): void;
58+
59+
// iOS only
60+
export declare function registerUserNotificationSettings(successCallback: () => void, errorCallback: (error: NSError) => void): void;

hooks/before-prepare.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var utils = require('./utils');
2+
3+
module.exports = function ($logger, $projectData) {
4+
5+
// No need to check if file exists cause it's a before-prepare hook
6+
// and if project targets Android, platforms dir is already created.
7+
// If Android is not set up correctly, platform is not added and we log an error
8+
9+
utils.setLogger(_log);
10+
11+
if (utils.targetsAndroid($projectData.projectDir)) {
12+
utils.addIfNecessary($projectData.platformsDir);
13+
}
14+
15+
function _log (str) {
16+
$logger.info('nativescript-push-notifications -- ' + str);
17+
}
18+
};

hooks/utils.js

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
var path = require('path');
2+
var fs = require('fs');
3+
var os = require('os');
4+
5+
var PLUGIN_VERSION = '+';
6+
var _log = console.log.bind(console);
7+
8+
function targetsAndroid (projectDir) {
9+
var pkg = require(path.join(projectDir, 'package.json'));
10+
if (!pkg.nativescript) {
11+
throw new Error('Not a NativeScript project');
12+
}
13+
14+
return ('tns-android' in pkg.nativescript);
15+
}
16+
17+
function buildGradleExists (platformsDir) {
18+
return fs.existsSync(_getBuildGradlePath(platformsDir));
19+
}
20+
21+
function checkForGoogleServicesJson (projectDir, resourcesDir) {
22+
var androidIsTargeted = targetsAndroid(projectDir);
23+
var resourcesPath = path.join(resourcesDir, 'Android', 'google-services.json');
24+
25+
if (androidIsTargeted && !fs.existsSync(resourcesPath)) {
26+
_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 |!|');
27+
}
28+
}
29+
30+
function addOnPluginInstall (platformsDir) {
31+
var path = _getBuildGradlePath(platformsDir);
32+
if (buildGradleExists(platformsDir)) {
33+
addIfNecessary(platformsDir);
34+
}
35+
}
36+
37+
function addIfNecessary (platformsDir) {
38+
_amendBuildGradle(platformsDir, function (pluginImported, pluginApplied, fileContents) {
39+
var newContents = fileContents;
40+
if (!pluginImported) {
41+
newContents = _addPluginImport(newContents);
42+
}
43+
44+
if (!pluginApplied) {
45+
newContents = _addPluginApplication(newContents);
46+
}
47+
return newContents;
48+
});
49+
}
50+
51+
function removeIfPresent (platformsDir) {
52+
_amendBuildGradle(platformsDir, function (pluginImported, pluginApplied, fileContents) {
53+
var newFileContents = fileContents;
54+
if (pluginImported) {
55+
newFileContents = _removePluginImport(newFileContents);
56+
}
57+
58+
if (pluginApplied) {
59+
newFileContents = _removePluginApplication(newFileContents);
60+
}
61+
return newFileContents;
62+
});
63+
}
64+
65+
function setLogger (logFunc) {
66+
_log = logFunc;
67+
}
68+
69+
// ============= private
70+
71+
var _quotesRegExp = '["\']';
72+
var _versionRegExp = '[^\'"]+';
73+
var _pluginImportName = 'com.google.gms:google-services';
74+
var _pluginApplicationName = 'com.google.gms.google-services';
75+
76+
function _amendBuildGradle (platformsDir, applyAmendment) {
77+
var path = _getBuildGradlePath(platformsDir);
78+
79+
if (!buildGradleExists(platformsDir)) {
80+
return _log('build.gradle file not found');
81+
}
82+
83+
var fileContents = fs.readFileSync(path, 'utf8');
84+
var pluginImported = _checkForImport(fileContents);
85+
var pluginApplied = _checkForApplication(fileContents);
86+
var newContents = applyAmendment(pluginImported, pluginApplied, fileContents);
87+
88+
fs.writeFileSync(path, newContents, 'utf8');
89+
}
90+
91+
function _removePluginImport (buildGradleContents) {
92+
var regExpStr = '\\s*classpath +' + _formNamePartOfRegExp(true) + '{0,0}:' + _versionRegExp + _quotesRegExp;
93+
var regExp = new RegExp(regExpStr, 'i');
94+
return buildGradleContents.replace(regExp, '');
95+
}
96+
97+
function _removePluginApplication (buildGradleContents) {
98+
var regExpStr = '\\s*apply plugin: +' + _formNamePartOfRegExp(false);
99+
var regExp = new RegExp(regExpStr, 'i');
100+
return buildGradleContents.replace(regExp, '');
101+
}
102+
103+
function _addPluginImport (buildGradleContents) {
104+
var androidGradle = 'com.android.tools.build:gradle';
105+
var insertBeforeDoubleQuotes = 'classpath "' + androidGradle;
106+
var insertBeforeSingleQoutes = 'classpath \'' + androidGradle;
107+
108+
var ind = buildGradleContents.indexOf(insertBeforeDoubleQuotes);
109+
if (ind === -1) {
110+
ind = buildGradleContents.indexOf(insertBeforeSingleQoutes);
111+
}
112+
113+
if (ind === -1) {
114+
_log('build.gradle has unexpected contents -- please check it manually');
115+
return buildGradleContents;
116+
}
117+
118+
var result = buildGradleContents.substring(0, ind);
119+
result += 'classpath "' + _pluginImportName + ':' + PLUGIN_VERSION + '"' + os.EOL;
120+
result += '\t\t' + insertBeforeDoubleQuotes;
121+
result += buildGradleContents.substring(ind + ('classpath "' + androidGradle).length);
122+
return result;
123+
}
124+
125+
function _addPluginApplication (buildGradleContents) {
126+
buildGradleContents += os.EOL + 'apply plugin: "' + _pluginApplicationName + '"' + os.EOL;
127+
return buildGradleContents;
128+
}
129+
130+
function _formNamePartOfRegExp (useImportName) {
131+
var name = useImportName ? _pluginImportName : _pluginApplicationName;
132+
return _quotesRegExp + name + _quotesRegExp;
133+
}
134+
135+
function _checkForImport (buildGradleContents) {
136+
var re = new RegExp('classpath +' + _formNamePartOfRegExp(true) + '{0,0}', 'i');
137+
return re.test(buildGradleContents);
138+
}
139+
140+
function _checkForApplication (buildGradleContents) {
141+
var re = new RegExp('apply plugin: +' + _formNamePartOfRegExp(false), 'i');
142+
return re.test(buildGradleContents);
143+
}
144+
145+
function _getBuildGradlePath (platformsDir) {
146+
return path.join(platformsDir, 'android', 'build.gradle');
147+
}
148+
149+
// ============= end private
150+
151+
module.exports = {
152+
removeIfPresent: removeIfPresent,
153+
setLogger: setLogger,
154+
addIfNecessary: addIfNecessary,
155+
targetsAndroid: targetsAndroid,
156+
buildGradleExists: buildGradleExists,
157+
addOnPluginInstall: addOnPluginInstall,
158+
checkForGoogleServicesJson: checkForGoogleServicesJson
159+
};

native-src/android/app/src/main/java/com/telerik/pushplugin/PushLifecycleCallbacks.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void onActivityPaused(Activity activity) {
4242
}
4343

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

4747
// the application has been resumed-> the push plugin is now in active/foreground state
4848
PushPlugin.isActive = true;

native-src/android/app/src/main/java/com/telerik/pushplugin/PushPlugin.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ private static JsonObjectExtended convertMapToJson(Map<String, String> data) {
8989
for (String key: data.keySet()) {
9090
json.put(key, JsonObjectExtended.wrap(data.get(key)));
9191
}
92+
json.put("foreground", PushPlugin.isActive);
9293
} catch (JSONException ex) {
9394
Log.d(TAG, "Error thrown while parsing push notification data bundle to json: " + ex.getMessage());
9495
}

package.json

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@
1111
"platforms": {
1212
"ios": "2.4.0",
1313
"android": "2.4.1"
14-
}
15-
}
14+
},
15+
"hooks": [
16+
{
17+
"type": "before-prepare",
18+
"script": "hooks/before-prepare.js",
19+
"inject": true
20+
}
21+
]
22+
},
23+
"scripts": {
24+
"postinstall": "node postinstall.js",
25+
"preuninstall": "node preuninstall.js"
26+
},
27+
"dependencies": {
28+
"nativescript-hook": "0.2.1"
29+
},
30+
"typings": "./definitions.d.ts"
1631
}

platforms/android/pushplugin.aar

34 Bytes
Binary file not shown.

postinstall.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require('nativescript-hook')(__dirname).postinstall();
2+
var path = require('path');
3+
var utils = require('./hooks/utils');
4+
var projDir = path.resolve(__dirname, '../../');
5+
6+
utils.checkForGoogleServicesJson(projDir, path.join(projDir, 'app', 'App_Resources'));
7+
utils.addOnPluginInstall(path.join(projDir, 'platforms'));

preuninstall.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
require('nativescript-hook')(__dirname).preuninstall();
2+
var path = require('path');
3+
var utils = require('./hooks/utils');
4+
var platformsDir = path.resolve(__dirname, '../../platforms');
5+
6+
utils.removeIfPresent(platformsDir);

push-plugin.android.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
module.exports = (function () {
22
var app = require('application');
3-
4-
(function() {
5-
// Hook on the application events
3+
var registerLifecycleEvents = function () {
64
com.telerik.pushplugin.PushLifecycleCallbacks.registerCallbacks(app.android.nativeApp);
7-
})();
5+
};
6+
7+
// Hook on the application events
8+
if (app.android.nativeApp) {
9+
registerLifecycleEvents();
10+
} else {
11+
app.on(app.launchEvent, registerLifecycleEvents);
12+
}
813

914
var pluginObject = {
1015
register: function (options, successCallback, errorCallback) {
1116
com.telerik.pushplugin.PushPlugin.register(app.android.context, options.senderID,
12-
//Success
1317
new com.telerik.pushplugin.PushPluginListener(
1418
{
1519
success: successCallback,

0 commit comments

Comments
 (0)