@octovise/react-native-sdk 1.0.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.
- package/CHANGELOG.md +43 -0
- package/LICENSE +21 -0
- package/README.md +160 -0
- package/android/src/main/java/com/octovise/sdk/OctoFirebaseMessagingService.kt +72 -0
- package/android/src/main/java/com/octovise/sdk/OctoPushDismissReceiver.kt +54 -0
- package/android/src/main/java/com/octovise/sdk/OctoPushModule.kt +26 -0
- package/android/src/main/java/com/octovise/sdk/OctoPushNotificationBuilder.kt +142 -0
- package/dist/api.d.ts +38 -0
- package/dist/api.js +210 -0
- package/dist/carouselStart.d.ts +1 -0
- package/dist/carouselStart.js +6 -0
- package/dist/components/OctoErrorBoundary.d.ts +15 -0
- package/dist/components/OctoErrorBoundary.js +28 -0
- package/dist/components/OctoImage.d.ts +23 -0
- package/dist/components/OctoImage.js +69 -0
- package/dist/components/OctoMessage.d.ts +9 -0
- package/dist/components/OctoMessage.js +189 -0
- package/dist/components/OctoModal.d.ts +13 -0
- package/dist/components/OctoModal.js +179 -0
- package/dist/components/OctoProvider.d.ts +14 -0
- package/dist/components/OctoProvider.js +92 -0
- package/dist/components/OctoToast.d.ts +13 -0
- package/dist/components/OctoToast.js +392 -0
- package/dist/debug.d.ts +2 -0
- package/dist/debug.js +15 -0
- package/dist/imageFit.d.ts +8 -0
- package/dist/imageFit.js +31 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +195 -0
- package/dist/latency.d.ts +17 -0
- package/dist/latency.js +11 -0
- package/dist/native.d.ts +1 -0
- package/dist/native.js +14 -0
- package/dist/navigation/reactNavigation.d.ts +12 -0
- package/dist/navigation/reactNavigation.js +24 -0
- package/dist/navigation/resolveCTA.d.ts +12 -0
- package/dist/navigation/resolveCTA.js +74 -0
- package/dist/push.d.ts +3 -0
- package/dist/push.js +129 -0
- package/dist/safeNavUrl.d.ts +2 -0
- package/dist/safeNavUrl.js +18 -0
- package/dist/screenStream.d.ts +17 -0
- package/dist/screenStream.js +126 -0
- package/dist/screenTargeting.d.ts +37 -0
- package/dist/screenTargeting.js +154 -0
- package/dist/session.d.ts +2 -0
- package/dist/session.js +22 -0
- package/dist/state.d.ts +8 -0
- package/dist/state.js +53 -0
- package/dist/telemetry.d.ts +6 -0
- package/dist/telemetry.js +65 -0
- package/dist/toastLayout.d.ts +2 -0
- package/dist/toastLayout.js +11 -0
- package/dist/types.d.ts +78 -0
- package/dist/types.js +7 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +4 -0
- package/ios/OctoviseNotificationExtension/NotificationService.swift +128 -0
- package/ios/OctoviseSDK/OctoPushModule.m +6 -0
- package/ios/OctoviseSDK/OctoPushModule.swift +27 -0
- package/package.json +57 -0
- package/react-native.config.js +16 -0
package/dist/state.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.canInit = canInit;
|
|
4
|
+
exports.markInit = markInit;
|
|
5
|
+
exports.isDuplicate = isDuplicate;
|
|
6
|
+
exports.setCurrentMessage = setCurrentMessage;
|
|
7
|
+
exports.clearCurrentMessage = clearCurrentMessage;
|
|
8
|
+
exports.startForegroundListener = startForegroundListener;
|
|
9
|
+
exports.stopForegroundListener = stopForegroundListener;
|
|
10
|
+
exports.reset = reset;
|
|
11
|
+
const react_native_1 = require("react-native");
|
|
12
|
+
const INIT_COOLDOWN_MS = 90 * 1000;
|
|
13
|
+
let lastInitAt = 0;
|
|
14
|
+
let lastShownMessageId = null;
|
|
15
|
+
let appStateSubscription = null;
|
|
16
|
+
function canInit() {
|
|
17
|
+
if (!lastInitAt)
|
|
18
|
+
return true;
|
|
19
|
+
return Date.now() - lastInitAt >= INIT_COOLDOWN_MS;
|
|
20
|
+
}
|
|
21
|
+
function markInit() {
|
|
22
|
+
lastInitAt = Date.now();
|
|
23
|
+
}
|
|
24
|
+
function isDuplicate(messageId) {
|
|
25
|
+
if (!messageId)
|
|
26
|
+
return false;
|
|
27
|
+
return messageId === lastShownMessageId;
|
|
28
|
+
}
|
|
29
|
+
function setCurrentMessage(messageId) {
|
|
30
|
+
lastShownMessageId = messageId ?? null;
|
|
31
|
+
}
|
|
32
|
+
function clearCurrentMessage() {
|
|
33
|
+
lastShownMessageId = null;
|
|
34
|
+
}
|
|
35
|
+
function startForegroundListener(onForeground) {
|
|
36
|
+
if (appStateSubscription)
|
|
37
|
+
return;
|
|
38
|
+
appStateSubscription = react_native_1.AppState.addEventListener('change', (nextState) => {
|
|
39
|
+
if (nextState === 'active' && canInit()) {
|
|
40
|
+
markInit();
|
|
41
|
+
onForeground();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function stopForegroundListener() {
|
|
46
|
+
appStateSubscription?.remove();
|
|
47
|
+
appStateSubscription = null;
|
|
48
|
+
}
|
|
49
|
+
function reset() {
|
|
50
|
+
lastInitAt = 0;
|
|
51
|
+
lastShownMessageId = null;
|
|
52
|
+
stopForegroundListener();
|
|
53
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function inMetricsSample(uid: number | string | null, digits: number[]): boolean;
|
|
2
|
+
export declare function configureTelemetry(uid: number | string): void;
|
|
3
|
+
export declare function setMetricSampleDigits(digits: unknown): void;
|
|
4
|
+
export declare function reportError(name: string, meta?: Record<string, unknown>): void;
|
|
5
|
+
export declare function reportMetric(name: string, value: number, meta?: Record<string, unknown>): void;
|
|
6
|
+
export declare function __resetTelemetryForTests(): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.inMetricsSample = inMetricsSample;
|
|
4
|
+
exports.configureTelemetry = configureTelemetry;
|
|
5
|
+
exports.setMetricSampleDigits = setMetricSampleDigits;
|
|
6
|
+
exports.reportError = reportError;
|
|
7
|
+
exports.reportMetric = reportMetric;
|
|
8
|
+
exports.__resetTelemetryForTests = __resetTelemetryForTests;
|
|
9
|
+
const api_1 = require("./api");
|
|
10
|
+
let sampleDigits = [];
|
|
11
|
+
let userId = null;
|
|
12
|
+
const queue = [];
|
|
13
|
+
let flushTimer = null;
|
|
14
|
+
const FLUSH_MS = 2000;
|
|
15
|
+
const FLUSH_SIZE = 20;
|
|
16
|
+
function inMetricsSample(uid, digits) {
|
|
17
|
+
if (uid == null || digits.length === 0)
|
|
18
|
+
return false;
|
|
19
|
+
const n = Number(uid);
|
|
20
|
+
if (!Number.isFinite(n))
|
|
21
|
+
return false;
|
|
22
|
+
return digits.includes(Math.abs(Math.trunc(n)) % 10);
|
|
23
|
+
}
|
|
24
|
+
function configureTelemetry(uid) {
|
|
25
|
+
userId = uid;
|
|
26
|
+
}
|
|
27
|
+
function setMetricSampleDigits(digits) {
|
|
28
|
+
sampleDigits = Array.isArray(digits) ? digits.filter((d) => typeof d === 'number') : [];
|
|
29
|
+
}
|
|
30
|
+
function reportError(name, meta) {
|
|
31
|
+
enqueue({ kind: 'error', name, meta });
|
|
32
|
+
}
|
|
33
|
+
function reportMetric(name, value, meta) {
|
|
34
|
+
if (!inMetricsSample(userId, sampleDigits))
|
|
35
|
+
return;
|
|
36
|
+
enqueue({ kind: 'metric', name, value, meta });
|
|
37
|
+
}
|
|
38
|
+
function enqueue(e) {
|
|
39
|
+
queue.push(e);
|
|
40
|
+
if (queue.length >= FLUSH_SIZE) {
|
|
41
|
+
flush();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!flushTimer)
|
|
45
|
+
flushTimer = setTimeout(flush, FLUSH_MS);
|
|
46
|
+
}
|
|
47
|
+
function flush() {
|
|
48
|
+
if (flushTimer) {
|
|
49
|
+
clearTimeout(flushTimer);
|
|
50
|
+
flushTimer = null;
|
|
51
|
+
}
|
|
52
|
+
if (queue.length === 0)
|
|
53
|
+
return;
|
|
54
|
+
const events = queue.splice(0, queue.length);
|
|
55
|
+
(0, api_1.sendTelemetry)(events);
|
|
56
|
+
}
|
|
57
|
+
function __resetTelemetryForTests() {
|
|
58
|
+
sampleDigits = [];
|
|
59
|
+
userId = null;
|
|
60
|
+
queue.length = 0;
|
|
61
|
+
if (flushTimer) {
|
|
62
|
+
clearTimeout(flushTimer);
|
|
63
|
+
flushTimer = null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toastLayout = toastLayout;
|
|
4
|
+
function toastLayout(hasImage, hasText, imagePosition) {
|
|
5
|
+
if (hasImage && !hasText)
|
|
6
|
+
return 'imageOnly';
|
|
7
|
+
if (!hasImage)
|
|
8
|
+
return 'textOnly';
|
|
9
|
+
const pos = imagePosition || 'left';
|
|
10
|
+
return pos === 'top' || pos === 'bottom' ? 'stacked' : 'carousel';
|
|
11
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export interface NavAdapter {
|
|
2
|
+
navigate: (routeName: string, params?: Record<string, string>) => void;
|
|
3
|
+
getCurrentScreen?: () => string | null;
|
|
4
|
+
subscribeScreenChange?: (cb: (screenName: string, params?: Record<string, unknown>) => void) => () => void;
|
|
5
|
+
}
|
|
6
|
+
export interface OctoRNConfig {
|
|
7
|
+
apiKey: string;
|
|
8
|
+
userId: number | string;
|
|
9
|
+
userHash?: string;
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
appVersion?: string;
|
|
12
|
+
onCTA?: (url: string) => void;
|
|
13
|
+
nav?: NavAdapter;
|
|
14
|
+
onEvent?: (event: EventType, meta: Partial<EventMeta>, sendId: number) => void;
|
|
15
|
+
registerPushToken?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface EntitySignal {
|
|
18
|
+
type: string;
|
|
19
|
+
id?: number | null;
|
|
20
|
+
ref?: string | null;
|
|
21
|
+
}
|
|
22
|
+
export interface InAppMessage {
|
|
23
|
+
id?: string;
|
|
24
|
+
_send_id?: number;
|
|
25
|
+
__timing?: {
|
|
26
|
+
t0: number;
|
|
27
|
+
tCheck: number;
|
|
28
|
+
};
|
|
29
|
+
layout: 'modal' | 'toast';
|
|
30
|
+
position?: 'center' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
31
|
+
mobile_position?: 'top' | 'center' | 'bottom';
|
|
32
|
+
size?: 'small' | 'medium' | 'large';
|
|
33
|
+
text_size?: 'small' | 'medium' | 'large';
|
|
34
|
+
text_align?: 'left' | 'center' | 'right';
|
|
35
|
+
title?: string;
|
|
36
|
+
body?: string;
|
|
37
|
+
image?: string;
|
|
38
|
+
image_position?: 'left' | 'right' | 'top' | 'bottom';
|
|
39
|
+
image_fit?: 'cover' | 'contain';
|
|
40
|
+
image_bg?: string;
|
|
41
|
+
cta: {
|
|
42
|
+
label: string;
|
|
43
|
+
url: string;
|
|
44
|
+
align?: 'left' | 'center' | 'right';
|
|
45
|
+
devices?: ('web' | 'mobile')[];
|
|
46
|
+
};
|
|
47
|
+
click_mode?: 'cta' | 'full' | 'none';
|
|
48
|
+
dismiss_label?: string;
|
|
49
|
+
colors?: {
|
|
50
|
+
primary?: string;
|
|
51
|
+
background?: string;
|
|
52
|
+
text?: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export type EventType = 'impression' | 'click' | 'dismiss' | 'received';
|
|
56
|
+
export interface EventMeta {
|
|
57
|
+
duration_ms: number;
|
|
58
|
+
time_to_first_interaction_ms: number | null;
|
|
59
|
+
close_method?: 'cta' | 'dismiss_button' | 'backdrop' | 'close_button';
|
|
60
|
+
device: 'mobile';
|
|
61
|
+
platform: 'ios' | 'android';
|
|
62
|
+
image_loaded: boolean;
|
|
63
|
+
latency?: import('./latency').LatencyBreakdown;
|
|
64
|
+
image_url?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface PushPayload {
|
|
67
|
+
source: 'octovise';
|
|
68
|
+
send_id: string;
|
|
69
|
+
campaign_id: string;
|
|
70
|
+
title: string;
|
|
71
|
+
body: string;
|
|
72
|
+
image_url?: string;
|
|
73
|
+
image_layout?: 'inline' | 'hero';
|
|
74
|
+
deep_link?: string;
|
|
75
|
+
channel_id?: string;
|
|
76
|
+
collapse_key?: string;
|
|
77
|
+
}
|
|
78
|
+
export declare function parsePushSendId(raw: unknown): number;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SDK_VERSION = "1.0.0";
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification Service Extension for Octovise push notifications on iOS.
|
|
3
|
+
*
|
|
4
|
+
* This runs in a separate process (even when the app is killed) and has
|
|
5
|
+
* ~30 seconds to modify the notification before iOS displays it.
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - Download the image and attach it as a media attachment
|
|
9
|
+
* - Track "received" event via POST /event
|
|
10
|
+
* - Only processes notifications where data.source == "octovise"
|
|
11
|
+
*
|
|
12
|
+
* Setup: the client adds this extension target to their Xcode project and
|
|
13
|
+
* sets the App Group so it can read the SDK config from shared UserDefaults.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import UserNotifications
|
|
17
|
+
|
|
18
|
+
class NotificationService: UNNotificationServiceExtension {
|
|
19
|
+
|
|
20
|
+
private var contentHandler: ((UNNotificationContent) -> Void)?
|
|
21
|
+
private var bestAttemptContent: UNMutableNotificationContent?
|
|
22
|
+
|
|
23
|
+
override func didReceive(
|
|
24
|
+
_ request: UNNotificationRequest,
|
|
25
|
+
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
|
|
26
|
+
) {
|
|
27
|
+
self.contentHandler = contentHandler
|
|
28
|
+
bestAttemptContent = request.content.mutableCopy() as? UNMutableNotificationContent
|
|
29
|
+
|
|
30
|
+
guard let content = bestAttemptContent,
|
|
31
|
+
let source = request.content.userInfo["source"] as? String,
|
|
32
|
+
source == "octovise" else {
|
|
33
|
+
// Not ours — pass through unmodified
|
|
34
|
+
contentHandler(request.content)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let userInfo = request.content.userInfo
|
|
39
|
+
|
|
40
|
+
// Track received (fire-and-forget)
|
|
41
|
+
trackReceived(userInfo: userInfo)
|
|
42
|
+
|
|
43
|
+
// Download and attach image
|
|
44
|
+
guard let imageUrlString = userInfo["image_url"] as? String,
|
|
45
|
+
let imageUrl = URL(string: imageUrlString) else {
|
|
46
|
+
contentHandler(content)
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
downloadImage(from: imageUrl) { attachment in
|
|
51
|
+
if let attachment = attachment {
|
|
52
|
+
content.attachments = [attachment]
|
|
53
|
+
}
|
|
54
|
+
contentHandler(content)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override func serviceExtensionTimeWillExpire() {
|
|
59
|
+
// iOS is about to kill us — deliver what we have
|
|
60
|
+
if let content = bestAttemptContent {
|
|
61
|
+
contentHandler?(content)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// MARK: - Image Download
|
|
66
|
+
|
|
67
|
+
private func downloadImage(from url: URL, completion: @escaping (UNNotificationAttachment?) -> Void) {
|
|
68
|
+
let task = URLSession.shared.downloadTask(with: url) { localUrl, response, error in
|
|
69
|
+
guard let localUrl = localUrl, error == nil else {
|
|
70
|
+
completion(nil)
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Move to a temp file with proper extension
|
|
75
|
+
let ext = url.pathExtension.isEmpty ? "jpg" : url.pathExtension
|
|
76
|
+
let tempUrl = FileManager.default.temporaryDirectory
|
|
77
|
+
.appendingPathComponent(UUID().uuidString)
|
|
78
|
+
.appendingPathExtension(ext)
|
|
79
|
+
|
|
80
|
+
do {
|
|
81
|
+
try FileManager.default.moveItem(at: localUrl, to: tempUrl)
|
|
82
|
+
let attachment = try UNNotificationAttachment(identifier: "octovise-image", url: tempUrl)
|
|
83
|
+
completion(attachment)
|
|
84
|
+
} catch {
|
|
85
|
+
completion(nil)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
task.resume()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// MARK: - Event Tracking
|
|
92
|
+
|
|
93
|
+
private func trackReceived(userInfo: [AnyHashable: Any]) {
|
|
94
|
+
// Read SDK config from shared App Group UserDefaults
|
|
95
|
+
guard let defaults = UserDefaults(suiteName: "group.octovise.sdk"),
|
|
96
|
+
let baseUrl = defaults.string(forKey: "base_url"),
|
|
97
|
+
let apiKey = defaults.string(forKey: "api_key"),
|
|
98
|
+
let userId = defaults.string(forKey: "user_id"),
|
|
99
|
+
let sendIdStr = userInfo["send_id"] as? String,
|
|
100
|
+
let sendId = Int(sendIdStr) else {
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let payload: [String: Any] = [
|
|
105
|
+
"user_id": userId,
|
|
106
|
+
"send_id": sendId,
|
|
107
|
+
"event": "received",
|
|
108
|
+
"meta": [
|
|
109
|
+
"device": "mobile",
|
|
110
|
+
"platform": "ios",
|
|
111
|
+
],
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
guard let url = URL(string: "\(baseUrl)/event"),
|
|
115
|
+
let body = try? JSONSerialization.data(withJSONObject: payload) else {
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
var request = URLRequest(url: url)
|
|
120
|
+
request.httpMethod = "POST"
|
|
121
|
+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
122
|
+
request.setValue(apiKey, forHTTPHeaderField: "X-API-Key")
|
|
123
|
+
request.httpBody = body
|
|
124
|
+
request.timeoutInterval = 5
|
|
125
|
+
|
|
126
|
+
URLSession.shared.dataTask(with: request).resume()
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native bridge module for iOS.
|
|
3
|
+
* Persists SDK config to shared App Group UserDefaults so the
|
|
4
|
+
* Notification Service Extension can access them.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
@objc(OctoPushModule)
|
|
10
|
+
class OctoPushModule: NSObject {
|
|
11
|
+
|
|
12
|
+
@objc
|
|
13
|
+
func configure(_ apiKey: String, userId: String, baseUrl: String) {
|
|
14
|
+
guard let defaults = UserDefaults(suiteName: "group.octovise.sdk") else {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
defaults.set(apiKey, forKey: "api_key")
|
|
18
|
+
defaults.set(userId, forKey: "user_id")
|
|
19
|
+
defaults.set(baseUrl, forKey: "base_url")
|
|
20
|
+
defaults.synchronize()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@objc
|
|
24
|
+
static func requiresMainQueueSetup() -> Bool {
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@octovise/react-native-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Octovise SDK for React Native — in-app messaging (push notifications in v1.1)",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"@react-native-firebase/messaging": ">=18",
|
|
17
|
+
"react": ">=18",
|
|
18
|
+
"react-native": ">=0.72",
|
|
19
|
+
"react-native-safe-area-context": ">=4"
|
|
20
|
+
},
|
|
21
|
+
"peerDependenciesMeta": {
|
|
22
|
+
"@react-native-firebase/messaging": {
|
|
23
|
+
"optional": true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@testing-library/react-native": "^12.9.0",
|
|
28
|
+
"@types/jest": "^29.5.12",
|
|
29
|
+
"@types/react": "^18",
|
|
30
|
+
"jest": "^29.7.0",
|
|
31
|
+
"react": "^18",
|
|
32
|
+
"react-native": "^0.74",
|
|
33
|
+
"react-native-safe-area-context": "^5.8.0",
|
|
34
|
+
"react-test-renderer": "^18.2.0",
|
|
35
|
+
"ts-jest": "^29.1.5",
|
|
36
|
+
"typescript": "^5.7.0"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist/",
|
|
40
|
+
"android/",
|
|
41
|
+
"ios/",
|
|
42
|
+
"react-native.config.js",
|
|
43
|
+
"CHANGELOG.md"
|
|
44
|
+
],
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/maurogallardo-cell/octovise-react-native-sdk.git"
|
|
48
|
+
},
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"keywords": [
|
|
51
|
+
"react-native",
|
|
52
|
+
"in-app-messaging",
|
|
53
|
+
"push-notifications",
|
|
54
|
+
"octovise",
|
|
55
|
+
"sdk"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Tell RN autolinking to skip the native (Android/iOS) modules for now.
|
|
2
|
+
// The Kotlin/Swift sources in android/ and ios/ are intended to be built
|
|
3
|
+
// as a proper RN native module in v2 (with build.gradle + podspec).
|
|
4
|
+
//
|
|
5
|
+
// For v1, the SDK is JS-only: in-app messaging works via fetch() + Modal/Animated.
|
|
6
|
+
// Push notifications (which need the native modules) are disabled by default.
|
|
7
|
+
// Setting platforms to null prevents autolinking from trying to compile
|
|
8
|
+
// the Kotlin/Swift sources without a proper module setup.
|
|
9
|
+
module.exports = {
|
|
10
|
+
dependency: {
|
|
11
|
+
platforms: {
|
|
12
|
+
android: null,
|
|
13
|
+
ios: null,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
}
|