@pushpushgo/react-native-push 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +20 -0
  2. package/PushPushGoRNPush.podspec +22 -0
  3. package/README.md +412 -0
  4. package/android/build.gradle +79 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +10 -0
  7. package/android/src/main/java/com/pushpushgo/bridge/reactnative/push/PushNotificationsActivityCallbacks.kt +36 -0
  8. package/android/src/main/java/com/pushpushgo/bridge/reactnative/push/PushNotificationsBeaconTranslator.kt +107 -0
  9. package/android/src/main/java/com/pushpushgo/bridge/reactnative/push/PushNotificationsContentProvider.kt +72 -0
  10. package/android/src/main/java/com/pushpushgo/bridge/reactnative/push/PushNotificationsError.kt +6 -0
  11. package/android/src/main/java/com/pushpushgo/bridge/reactnative/push/PushNotificationsModule.kt +54 -0
  12. package/android/src/main/java/com/pushpushgo/bridge/reactnative/push/PushNotificationsPackage.kt +36 -0
  13. package/ios/Bridge/PushNotificationsBeaconTranslator.swift +80 -0
  14. package/ios/Bridge/PushNotificationsModule.h +10 -0
  15. package/ios/Bridge/PushNotificationsModule.mm +53 -0
  16. package/ios/Bridge/PushNotificationsModuleDelegate.swift +68 -0
  17. package/ios/PushNotificationsRN.swift +35 -0
  18. package/lib/module/beacon/Beacon.js +51 -0
  19. package/lib/module/beacon/Beacon.js.map +1 -0
  20. package/lib/module/beacon/BeaconTag.js +32 -0
  21. package/lib/module/beacon/BeaconTag.js.map +1 -0
  22. package/lib/module/index.js +37 -0
  23. package/lib/module/index.js.map +1 -0
  24. package/lib/module/package.json +1 -0
  25. package/lib/module/specs/NativePushNotifications.js +5 -0
  26. package/lib/module/specs/NativePushNotifications.js.map +1 -0
  27. package/lib/typescript/package.json +1 -0
  28. package/lib/typescript/src/beacon/Beacon.d.ts +38 -0
  29. package/lib/typescript/src/beacon/Beacon.d.ts.map +1 -0
  30. package/lib/typescript/src/beacon/BeaconTag.d.ts +31 -0
  31. package/lib/typescript/src/beacon/BeaconTag.d.ts.map +1 -0
  32. package/lib/typescript/src/index.d.ts +12 -0
  33. package/lib/typescript/src/index.d.ts.map +1 -0
  34. package/lib/typescript/src/specs/NativePushNotifications.d.ts +22 -0
  35. package/lib/typescript/src/specs/NativePushNotifications.d.ts.map +1 -0
  36. package/package.json +168 -0
  37. package/src/beacon/Beacon.ts +84 -0
  38. package/src/beacon/BeaconTag.ts +52 -0
  39. package/src/index.tsx +62 -0
  40. package/src/specs/NativePushNotifications.ts +25 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 PushPushGo
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
@@ -0,0 +1,22 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "PushPushGoRNPush"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported }
14
+ s.source = { :git => "https://github.com/ppgco/react-native-sdk.git", :tag => "#{s.version}" }
15
+
16
+ s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
17
+ s.private_header_files = "ios/**/*.h"
18
+
19
+ s.dependency "PPG_framework", ">= 4.2"
20
+
21
+ install_modules_dependencies(s)
22
+ end
package/README.md ADDED
@@ -0,0 +1,412 @@
1
+ # React Native SDK
2
+
3
+ PushPushGo Push Notifications SDK for React Native. Supports Android (FCM / HMS) and iOS (APNS).
4
+
5
+ ---
6
+
7
+ ## Requirements
8
+
9
+ - Node 22+
10
+ - Android Studio
11
+ - Xcode
12
+
13
+ ---
14
+
15
+ ## Expo Projects
16
+
17
+ If you are using the Expo Managed workflow, you will need to eject your project to switch to the Expo Bare workflow.
18
+
19
+ Run the following command in your project root:
20
+
21
+ ```bash
22
+ npx expo prebuild
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Android Integration
28
+
29
+ ### Preparation
30
+
31
+ 1. Remove other push SDKs or custom FCM/HMS implementations.
32
+ 2. Connect your app to a push provider.
33
+ 3. Prepare provider configuration files:
34
+ - FCM: `google-services.json`
35
+ - HMS: `agconnect-services.json`
36
+ 4. Integrate the provider in the PushPushGo app:
37
+ - Project → Settings → Integration
38
+ - See FCM or HMS sections below for details.
39
+ 5. Collect your PushPushGo Project ID and API Key.
40
+
41
+ ---
42
+
43
+ ### Installation
44
+
45
+ ```sh
46
+ npm install @pushpushgo/react-native-push
47
+ # or
48
+ yarn add @pushpushgo/react-native-push
49
+ ```
50
+
51
+ ---
52
+
53
+ ### FCM (Firebase Cloud Messaging)
54
+
55
+ #### Provider credentials
56
+
57
+ 1. Open **Firebase Console**.
58
+ 2. Navigate to **Project settings** → **Cloud Messaging**.
59
+ 3. Click **Manage service accounts**.
60
+ 4. Select your service account email.
61
+ 5. Open the **Keys** tab.
62
+ 6. Click **Add key** → **Create new key**.
63
+ 7. Choose **JSON** format and download the file.
64
+ 8. Upload the JSON file in the PushPushGo **FCM** integration section.
65
+
66
+ #### FCM configuration
67
+
68
+ Place `google-services.json` in the app module root:
69
+
70
+ ```
71
+ android/app/google-services.json
72
+ ```
73
+
74
+ #### Gradle setup
75
+
76
+ ```gradle
77
+ // android/build.gradle
78
+ buildscript {
79
+ dependencies {
80
+ classpath("com.google.gms:google-services:4.4.4")
81
+ }
82
+ }
83
+ ```
84
+
85
+ ```gradle
86
+ // android/app/build.gradle
87
+
88
+ apply plugin: 'com.google.gms.google-services'
89
+
90
+ dependencies {
91
+ implementation platform('com.google.firebase:firebase-bom:34.9.0')
92
+ implementation 'com.google.firebase:firebase-messaging'
93
+ }
94
+ ```
95
+
96
+ ---
97
+
98
+ ### HMS (Huawei Push Kit)
99
+
100
+ #### Provider credentials
101
+
102
+ 1. Open **Huawei Developers Console**.
103
+ 2. Navigate to your project.
104
+ 3. Open **Project settings**.
105
+ 4. Collect the required values:
106
+ - `appId`
107
+ - `authUrl`
108
+ - `pushUrl`
109
+ - `appSecret`
110
+ 5. Provide these credentials in the PushPushGo **HMS** integration section.
111
+
112
+ #### HMS configuration
113
+
114
+ Place `agconnect-services.json` in the app module root:
115
+
116
+ ```
117
+ android/app/agconnect-services.json
118
+ ```
119
+
120
+ #### Gradle setup
121
+
122
+ ```gradle
123
+ // android/build.gradle
124
+ buildscript {
125
+ repositories {
126
+ maven {
127
+ url('https://developer.huawei.com/repo/')
128
+ }
129
+ }
130
+
131
+ dependencies {
132
+ classpath('com.huawei.agconnect:agcp:1.9.1.304')
133
+ }
134
+ }
135
+
136
+ allprojects {
137
+ repositories {
138
+ maven {
139
+ url('https://developer.huawei.com/repo/')
140
+ }
141
+ }
142
+ }
143
+ ```
144
+
145
+ ```gradle
146
+ // android/app/build.gradle
147
+
148
+ apply plugin: 'com.huawei.agconnect'
149
+
150
+ dependencies {
151
+ implementation 'com.huawei.agconnect:agconnect-core:1.9.1.304'
152
+ implementation 'com.huawei.hms:push:6.13.0.300'
153
+ }
154
+ ```
155
+
156
+ ---
157
+
158
+ ### Android Configuration
159
+
160
+ #### AndroidManifest.xml
161
+
162
+ Add your Project ID and API Key inside `<application>`:
163
+
164
+ ```xml
165
+ <meta-data
166
+ android:name="com.pushpushgo.projectId"
167
+ android:value="{projectId}" />
168
+
169
+ <meta-data
170
+ android:name="com.pushpushgo.apiKey"
171
+ android:value="{apiKey}" />
172
+ ```
173
+
174
+ #### Handling notification clicks
175
+
176
+ To ensure correct handling of notification taps:
177
+
178
+ 1. Set `android:launchMode` to `singleTop` on your activity.
179
+ 2. Add the following `intent-filter`.
180
+
181
+ ```xml
182
+ <activity android:launchMode="singleTop">
183
+ <intent-filter>
184
+ <action android:name="APP_PUSH_CLICK" />
185
+ <category android:name="android.intent.category.DEFAULT" />
186
+ </intent-filter>
187
+ </activity>
188
+ ```
189
+
190
+ ### Additional info
191
+
192
+ - https://docs.pushpushgo.company/mobile-push/google-android
193
+ - https://docs.pushpushgo.company/mobile-push/huawei-android
194
+
195
+ ---
196
+
197
+ ## iOS Integration
198
+
199
+ ### 1. Modify Podfile
200
+
201
+ ```rb
202
+ # ios/Podfile
203
+
204
+ # Add PPG_framework pod to existing main application target
205
+ target '<application_name>' do
206
+
207
+ pod 'PPG_framework', :git => 'https://github.com/ppgco/ios-sdk.git', :tag => '4.2.0'
208
+
209
+ end
210
+
211
+ # Add the following code to the post_install section
212
+ post_install do |installer|
213
+ installer.pods_project.targets.each do |target|
214
+ target.build_configurations.each do |config|
215
+ config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'No'
216
+ end
217
+ end
218
+ end
219
+ ```
220
+
221
+ ### 2. Install pods
222
+
223
+ Under ios/ directory run `pod install`.
224
+
225
+ ### 3. Open workspace
226
+
227
+ Open iOS project in Xcode (`ios/*.xcworkspace`).
228
+
229
+ ### 4. Modify AppDelegate
230
+
231
+ ```swift
232
+ // ios/<name>/AppDelegate.swift
233
+
234
+ import PushPushGoRNPush
235
+
236
+ public override func application(
237
+ _ application: UIApplication,
238
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
239
+ ) -> Bool {
240
+ // At the beginning of this method, initialize the PushNotificationsRN library
241
+
242
+ PushNotificationsRN.initialize(
243
+ projectId: "<YOUR-PROJECT-ID>",
244
+ apiKey: "<YOUR-API-KEY>",
245
+ appGroupId: "<YOUR-APP-GROUP-ID>"
246
+ )
247
+
248
+ // ...
249
+ }
250
+
251
+ // Add the following code
252
+
253
+ public override func applicationDidBecomeActive(_ application: UIApplication) {
254
+ PushNotificationsRN.applicationDidBecomeActive()
255
+ }
256
+
257
+ public override func application(
258
+ _ application: UIApplication,
259
+ didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
260
+ ) {
261
+ PushNotificationsRN.applicationDidRegisterForRemoteNotificationsWithDeviceToken(deviceToken: deviceToken)
262
+ }
263
+
264
+ public override func application(
265
+ _ application: UIApplication,
266
+ didReceiveRemoteNotification userInfo: [AnyHashable : Any],
267
+ fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
268
+ ) {
269
+ PushNotificationsRN.applicationDidReceiveRemoteNotification(userInfo: userInfo, fetchCompletionHandler: completionHandler)
270
+ }
271
+ ```
272
+
273
+ ### 5. Add required capabilities
274
+
275
+ - Click on top item in your project hierarchy
276
+ - Select your project on target list
277
+ - Select `Signing & Capabilities`
278
+ - You can add capability by clicking on `+ Capability` button that is placed under `Signing & Capabilities` button
279
+ - Add `Background Modes` capability unless it is already on your capability list. Then select `Remote notifications`
280
+ - Add `Push notifications` capability unless it is already on your capability list
281
+ - Add `App Groups`. You can use your default app group ID or add new one
282
+ - Make sure that your `Provisioning Profile` has required capabilities. If you didn't add them while creating `Provisioning Profile` for your app you should go to your Apple Developer Center to add them. Then refresh your profile in Xcode project.
283
+
284
+ #### How to add new group to your provisioning profile?
285
+
286
+ - Go to Apple Developers and navigate to Certificates, Identifiers & Profiles. Then go to Identifiers and in the right corner change App IDs to AppGroups. You can add new group here.
287
+ - Now you can go back to Identifiers, choose your app identifier and add AppGroup capability. Remember to check your new group.
288
+
289
+ ### 6. Create Notification Service Extension (NSE)
290
+
291
+ - Go to `File -> New -> Target`
292
+ - Select `Notification Service Extension`
293
+ - Choose a suitable name for it
294
+ - Right click on the created NSE and select `Convert To Group`
295
+ - Select your NSE on target list
296
+ - Select `Signing & Capabilities`
297
+ - Click on `+ Capability` button, under `Signing & Capabilities`, and add AppGroup capability with the exact same appGroupId as in the main application target and in the code
298
+ - Modify `Podfile` and add NSE target
299
+
300
+ ```rb
301
+ # ios/Podfile
302
+
303
+ # Replace PushPushGoRNNSE with the name of your NSE
304
+ target 'PushPushGoRNNSE' do
305
+ use_modular_headers!
306
+
307
+ pod 'PPG_framework', :git => 'https://github.com/ppgco/ios-sdk.git', :tag => '4.2.0'
308
+ end
309
+ ```
310
+
311
+ - In ios/ directory run `pod install`
312
+ - Select your NSE on target list, in `General` > `Frameworks and Libraries` add `libPPG_framework.a`
313
+ - Modify `NotificationService.swift` file in the created NSE and fill in the appGroupId value
314
+
315
+ ```swift
316
+ // ios/<NSE>/NotificationService.swift
317
+
318
+ import PPG_framework
319
+
320
+ // replace didReceive function with the following implementation
321
+ override func didReceive(
322
+ _ request: UNNotificationRequest,
323
+ withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
324
+ ) {
325
+ self.contentHandler = contentHandler
326
+ self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
327
+
328
+ guard let content = bestAttemptContent else { return }
329
+
330
+ // replace with your appGroupId
331
+ SharedData.shared.appGroupId = "<YOUR-APP-GROUP-ID>"
332
+
333
+ let group = DispatchGroup()
334
+
335
+ group.enter()
336
+ PPG.notificationDelivered(notificationRequest: request) { _ in
337
+ group.leave()
338
+ }
339
+
340
+ group.enter()
341
+ DispatchQueue.global().async { [weak self] in
342
+ self?.bestAttemptContent = PPG.modifyNotification(content)
343
+ group.leave()
344
+ }
345
+
346
+ group.notify(queue: .main) {
347
+ contentHandler(self.bestAttemptContent ?? content)
348
+ }
349
+ }
350
+ ```
351
+
352
+ ### 7. Ensure minimum deployment version
353
+
354
+ Ensure that application and NSE targets have the same minimum iOS version requirement - `General` > `Minimum Deployments`.
355
+
356
+ ### 8. Additional info
357
+
358
+ - https://docs.pushpushgo.company/mobile-push/apple-ios
359
+
360
+ ---
361
+
362
+ ## Usage
363
+
364
+ ```ts
365
+ import { PushNotifications } from '@pushpushgo/react-native-push';
366
+
367
+ PushNotifications.subscribeToNotifications()
368
+ .then((subscriberId) => console.log(`subscriberId: ${subscriberId}`))
369
+ .catch((e) =>
370
+ console.error(`Cannot subscribe to notifications: ${e?.message}`)
371
+ );
372
+
373
+ PushNotifications.unsubscribeFromNotifications()
374
+ .then(() => console.log('Unsubscribed from notifications'))
375
+ .catch((e) =>
376
+ console.error(`Cannot unsubscribe from notifications: ${e?.message}`)
377
+ );
378
+
379
+ PushNotifications.getSubscriberId()
380
+ .then((subscriberId) =>
381
+ console.log(`subscriberId: ${subscriberId ?? 'unsubscribed'}`)
382
+ )
383
+ .catch((e) => console.error(`Cannot get subscriberId: ${e?.message}`));
384
+
385
+ const beacon = Beacon.builder()
386
+ .set('a-flag', true)
387
+ .set('b-flag', 123)
388
+ .set('c-flag', 'hello-world')
389
+ .appendTag(BeaconTag.fromTagAndLabel('my-tag', 'my-label'))
390
+ .appendTag(
391
+ new BeaconTag({
392
+ tag: 'my-tag-2',
393
+ label: 'my-label-2',
394
+ strategy: BeaconTagStrategy.REWRITE,
395
+ ttl: 1000,
396
+ })
397
+ )
398
+ .setCustomId('my-custom-id')
399
+ .assignToGroup('my-group-name') // Assign subscriber to dynamic group
400
+ .unassignFromGroup('my-group-name') // Unassign subscriber from dynamic group
401
+ .build();
402
+
403
+ PushNotifications.sendBeacon(beacon)
404
+ .then(() => console.log('Beacon sent'))
405
+ .catch((e) => `Cannot send beacon: ${e?.message}`);
406
+ ```
407
+
408
+ ---
409
+
410
+ ## License
411
+
412
+ MIT
@@ -0,0 +1,79 @@
1
+ buildscript {
2
+ ext.getExtOrDefault = {name ->
3
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['ReactNativeSdk_' + name]
4
+ }
5
+
6
+ repositories {
7
+ google()
8
+ mavenCentral()
9
+ }
10
+
11
+ dependencies {
12
+ classpath "com.android.tools.build:gradle:9.0.0"
13
+ // noinspection DifferentKotlinGradleVersion
14
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
15
+ }
16
+ }
17
+
18
+
19
+ apply plugin: "com.android.library"
20
+ apply plugin: "kotlin-android"
21
+ apply plugin: "com.facebook.react"
22
+
23
+ def getExtOrIntegerDefault(name) {
24
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["ReactNativeSdk_" + name]).toInteger()
25
+ }
26
+
27
+ android {
28
+ namespace "com.pushpushgo.bridge.reactnative.push"
29
+
30
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
31
+
32
+ defaultConfig {
33
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
34
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
35
+ }
36
+
37
+ buildFeatures {
38
+ buildConfig true
39
+ }
40
+
41
+ buildTypes {
42
+ release {
43
+ minifyEnabled false
44
+ }
45
+ }
46
+
47
+ lintOptions {
48
+ disable "GradleCompatible"
49
+ }
50
+
51
+ compileOptions {
52
+ sourceCompatibility JavaVersion.VERSION_1_8
53
+ targetCompatibility JavaVersion.VERSION_1_8
54
+ }
55
+
56
+ sourceSets {
57
+ main {
58
+ java.srcDirs += [
59
+ "generated/java",
60
+ "generated/jni"
61
+ ]
62
+ }
63
+ }
64
+ }
65
+
66
+ repositories {
67
+ maven { url 'https://jitpack.io' }
68
+ mavenCentral()
69
+ google()
70
+ }
71
+
72
+ def kotlin_version = getExtOrDefault("kotlinVersion")
73
+
74
+ dependencies {
75
+ implementation "com.facebook.react:react-android"
76
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
77
+ implementation "com.github.ppgco.android-sdk:sdk:3.1.0"
78
+ implementation 'com.google.guava:guava:33.5.0-android'
79
+ }
@@ -0,0 +1,5 @@
1
+ ReactNativeSdk_kotlinVersion=2.0.21
2
+ ReactNativeSdk_minSdkVersion=24
3
+ ReactNativeSdk_targetSdkVersion=34
4
+ ReactNativeSdk_compileSdkVersion=35
5
+ ReactNativeSdk_ndkVersion=27.1.12297006
@@ -0,0 +1,10 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <application>
3
+ <provider
4
+ android:name="com.pushpushgo.bridge.reactnative.push.PushNotificationsContentProvider"
5
+ android:authorities="${applicationId}.PushPushGoContentProvider"
6
+ android:exported="false"
7
+ android:initOrder="100"
8
+ />
9
+ </application>
10
+ </manifest>
@@ -0,0 +1,36 @@
1
+ package com.pushpushgo.bridge.reactnative.push
2
+
3
+ import android.app.Activity
4
+ import android.app.Application.ActivityLifecycleCallbacks
5
+ import android.os.Bundle
6
+ import com.pushpushgo.sdk.PushPushGo
7
+
8
+ internal class PushNotificationsActivityCallbacks : ActivityLifecycleCallbacks {
9
+ override fun onActivityCreated(
10
+ activity: Activity,
11
+ savedInstanceState: Bundle?,
12
+ ) {
13
+ if (PushPushGo.isInitialized() && savedInstanceState == null) {
14
+ PushPushGo.getInstance().handleBackgroundNotificationClick(activity.intent)
15
+ }
16
+ }
17
+
18
+ override fun onActivityResumed(activity: Activity) {
19
+ if (PushPushGo.isInitialized()) {
20
+ PushPushGo.getInstance().handleBackgroundNotificationClick(activity.intent)
21
+ }
22
+ }
23
+
24
+ override fun onActivityDestroyed(activity: Activity) = Unit
25
+
26
+ override fun onActivityPaused(activity: Activity) = Unit
27
+
28
+ override fun onActivitySaveInstanceState(
29
+ activity: Activity,
30
+ outState: Bundle,
31
+ ) = Unit
32
+
33
+ override fun onActivityStarted(activity: Activity) = Unit
34
+
35
+ override fun onActivityStopped(activity: Activity) = Unit
36
+ }
@@ -0,0 +1,107 @@
1
+ package com.pushpushgo.bridge.reactnative.push
2
+
3
+ import com.facebook.react.bridge.ReadableMap
4
+ import com.facebook.react.bridge.ReadableType
5
+ import com.pushpushgo.sdk.BeaconBuilder
6
+ import com.pushpushgo.sdk.PushPushGo
7
+
8
+ private data class TranslatedBeaconTag(
9
+ val tag: String,
10
+ val label: String,
11
+ val strategy: String,
12
+ val ttl: Int,
13
+ )
14
+
15
+ internal class PushNotificationsBeaconTranslator {
16
+ companion object {
17
+ private fun translateSelectors(
18
+ map: ReadableMap,
19
+ beacon: BeaconBuilder,
20
+ ) {
21
+ val selectors = map.getMap("selectors")
22
+ val selectorsIterator = selectors?.keySetIterator()
23
+
24
+ while (selectorsIterator?.hasNextKey() == true) {
25
+ val key = selectorsIterator.nextKey()
26
+ val value: Any? =
27
+ when (selectors.getType(key)) {
28
+ ReadableType.String -> selectors.getString(key)
29
+ ReadableType.Number -> selectors.getDouble(key)
30
+ ReadableType.Boolean -> selectors.getBoolean(key)
31
+ else -> throw PushNotificationsError("Unexpected selector value type")
32
+ }
33
+
34
+ value?.let { beacon.set(key, it) }
35
+ }
36
+ }
37
+
38
+ private fun translateTag(tag: ReadableMap): TranslatedBeaconTag? {
39
+ val name = tag.getString("tag") ?: return null
40
+ val label = tag.getString("label") ?: "default"
41
+ val strategy = tag.getString("strategy") ?: "append"
42
+ val ttl = tag.getInt("ttl")
43
+
44
+ if (strategy != "append" && strategy != "rewrite") {
45
+ throw PushNotificationsError("Unexpected beacon tag strategy")
46
+ }
47
+
48
+ return TranslatedBeaconTag(
49
+ tag = name,
50
+ label = label,
51
+ strategy = strategy,
52
+ ttl = ttl,
53
+ )
54
+ }
55
+
56
+ private fun translateTags(
57
+ map: ReadableMap,
58
+ beacon: BeaconBuilder,
59
+ ) {
60
+ val tags = map.getArray("tags") ?: return
61
+
62
+ for (i in 0 until tags.size()) {
63
+ val rawTag = tags.getMap(i) ?: continue
64
+ val tag = translateTag(rawTag) ?: continue
65
+
66
+ beacon.appendTag(
67
+ tag = tag.tag,
68
+ label = tag.label,
69
+ strategy = tag.strategy,
70
+ ttl = tag.ttl,
71
+ )
72
+ }
73
+ }
74
+
75
+ private fun translateTagsToDelete(
76
+ map: ReadableMap,
77
+ beacon: BeaconBuilder,
78
+ ) {
79
+ val rawTagsToDelete = map.getArray("tagsToDelete") ?: return
80
+ val tagsToDelete = mutableMapOf<String, String>()
81
+
82
+ for (i in 0 until rawTagsToDelete.size()) {
83
+ val rawTag = rawTagsToDelete.getMap(i) ?: continue
84
+ val tag = translateTag(rawTag) ?: continue
85
+
86
+ tagsToDelete[tag.tag] = tag.label
87
+ }
88
+
89
+ beacon.removeTags(tagsToDelete)
90
+ }
91
+
92
+ fun translate(map: ReadableMap): BeaconBuilder {
93
+ val beacon = PushPushGo.getInstance().createBeacon()
94
+
95
+ translateSelectors(map, beacon)
96
+ translateTags(map, beacon)
97
+ translateTagsToDelete(map, beacon)
98
+
99
+ beacon.setCustomId(map.getString("customId"))
100
+
101
+ map.getString("assignToGroup")?.let { beacon.assignToGroup(it) }
102
+ map.getString("unassignFromGroup")?.let { beacon.unassignFromGroup(it) }
103
+
104
+ return beacon
105
+ }
106
+ }
107
+ }