@zellio/chat-react-native 0.0.0-stage → 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/LICENSE +202 -0
- package/README.md +239 -2
- package/ZellioChatReactNative.podspec +30 -0
- package/android/build.gradle +62 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/ai/zellio/chat/reactnative/ZellioChatModule.kt +214 -0
- package/android/src/main/java/ai/zellio/chat/reactnative/ZellioChatPackage.kt +25 -0
- package/app.plugin.js +4 -0
- package/ios/RNZellioChat.h +5 -0
- package/ios/RNZellioChat.mm +116 -0
- package/ios/ZCRNBridge.swift +217 -0
- package/ios/vendor/resources/PrivacyInfo.xcprivacy +99 -0
- package/ios/vendor/swift/ZellioChat/Model/ChatModel.swift +261 -0
- package/ios/vendor/swift/ZellioChat/Platform/Platform.swift +124 -0
- package/ios/vendor/swift/ZellioChat/Platform/URLSessionTransport.swift +175 -0
- package/ios/vendor/swift/ZellioChat/Preview/Previews.swift +62 -0
- package/ios/vendor/swift/ZellioChat/Public/InAppBanner.swift +155 -0
- package/ios/vendor/swift/ZellioChat/Public/PublicTypes.swift +141 -0
- package/ios/vendor/swift/ZellioChat/Public/Runtime.swift +406 -0
- package/ios/vendor/swift/ZellioChat/Public/ZellioChat.swift +209 -0
- package/ios/vendor/swift/ZellioChat/Theme/ChatTheme.swift +185 -0
- package/ios/vendor/swift/ZellioChat/Thread/AttachmentPicker.swift +354 -0
- package/ios/vendor/swift/ZellioChat/Thread/ComposerBar.swift +355 -0
- package/ios/vendor/swift/ZellioChat/Thread/ThreadCells.swift +776 -0
- package/ios/vendor/swift/ZellioChat/Thread/ThreadViewController.swift +703 -0
- package/ios/vendor/swift/ZellioChat/Views/ChatRootView.swift +154 -0
- package/ios/vendor/swift/ZellioChat/Views/Components.swift +335 -0
- package/ios/vendor/swift/ZellioChat/Views/HomeView.swift +413 -0
- package/ios/vendor/swift/ZellioChatCore/ChatModels.swift +373 -0
- package/ios/vendor/swift/ZellioChatCore/ConfigModels.swift +389 -0
- package/ios/vendor/swift/ZellioChatCore/Engine.swift +325 -0
- package/ios/vendor/swift/ZellioChatCore/Errors.swift +158 -0
- package/ios/vendor/swift/ZellioChatCore/Generated/ChatStringTable.swift +125 -0
- package/ios/vendor/swift/ZellioChatCore/Outbox.swift +223 -0
- package/ios/vendor/swift/ZellioChatCore/Push.swift +74 -0
- package/ios/vendor/swift/ZellioChatCore/Realtime.swift +328 -0
- package/ios/vendor/swift/ZellioChatCore/Session.swift +210 -0
- package/ios/vendor/swift/ZellioChatCore/Storage.swift +201 -0
- package/ios/vendor/swift/ZellioChatCore/Strings.swift +104 -0
- package/ios/vendor/swift/ZellioChatCore/Theme.swift +238 -0
- package/ios/vendor/swift/ZellioChatCore/ThreadController.swift +319 -0
- package/ios/vendor/swift/ZellioChatCore/Timeline.swift +157 -0
- package/ios/vendor/swift/ZellioChatCore/Transport.swift +236 -0
- package/ios/vendor/swift/ZellioChatCore/Util.swift +137 -0
- package/lib/NativeZellioChat.d.ts +34 -0
- package/lib/NativeZellioChat.js +4 -0
- package/lib/index.d.ts +37 -0
- package/lib/index.js +241 -0
- package/lib/types.d.ts +54 -0
- package/lib/types.js +2 -0
- package/lib/version.d.ts +4 -0
- package/lib/version.js +7 -0
- package/package.json +75 -4
- package/plugin/build/index.js +73 -0
- package/src/NativeZellioChat.ts +30 -0
- package/src/index.ts +237 -0
- package/src/types.ts +56 -0
- package/src/version.ts +5 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TOKEN_TIMEOUT_MS = exports.VERSION = void 0;
|
|
7
|
+
exports.configure = configure;
|
|
8
|
+
exports.identify = identify;
|
|
9
|
+
exports.logout = logout;
|
|
10
|
+
exports.present = present;
|
|
11
|
+
exports.presentConversation = presentConversation;
|
|
12
|
+
exports.dismiss = dismiss;
|
|
13
|
+
exports.setContext = setContext;
|
|
14
|
+
exports.getUnreadCount = getUnreadCount;
|
|
15
|
+
exports.addUnreadListener = addUnreadListener;
|
|
16
|
+
exports.addEventListener = addEventListener;
|
|
17
|
+
exports.setPushToken = setPushToken;
|
|
18
|
+
exports.isZellioPush = isZellioPush;
|
|
19
|
+
exports.handlePush = handlePush;
|
|
20
|
+
exports.handleNotificationTap = handleNotificationTap;
|
|
21
|
+
const NativeZellioChat_1 = __importDefault(require("./NativeZellioChat"));
|
|
22
|
+
const version_1 = require("./version");
|
|
23
|
+
var version_2 = require("./version");
|
|
24
|
+
Object.defineProperty(exports, "VERSION", { enumerable: true, get: function () { return version_2.VERSION; } });
|
|
25
|
+
/** Native asks for a token at most this long before it gives up. */
|
|
26
|
+
exports.TOKEN_TIMEOUT_MS = 15000;
|
|
27
|
+
let tokenProvider = null;
|
|
28
|
+
let tokenSubscription = null;
|
|
29
|
+
function reportMisuse(call, error) {
|
|
30
|
+
// Only the call name and the error kind. Never the arguments: they can hold a token.
|
|
31
|
+
const kind = error instanceof Error ? error.name : 'unknown';
|
|
32
|
+
console.warn(`[ZellioChat] ${call} failed (${kind})`);
|
|
33
|
+
}
|
|
34
|
+
function guard(call, run) {
|
|
35
|
+
try {
|
|
36
|
+
run();
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
reportMisuse(call, error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Call once at app start. Cheap: no network on the calling thread, no UI. */
|
|
43
|
+
function configure(config) {
|
|
44
|
+
guard('configure', () => {
|
|
45
|
+
const { appKey, theme, ...rest } = config;
|
|
46
|
+
NativeZellioChat_1.default.configure(appKey, withoutUndefined({
|
|
47
|
+
...rest,
|
|
48
|
+
themeMode: theme?.mode,
|
|
49
|
+
primaryColor: theme?.primaryColor,
|
|
50
|
+
customerMessageColor: theme?.customerMessageColor,
|
|
51
|
+
surfaceColor: theme?.surfaceColor,
|
|
52
|
+
wrapper: version_1.WRAPPER,
|
|
53
|
+
}));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/** The bridge turns `undefined` into null. Native code reads "missing" more simply than "null". */
|
|
57
|
+
function withoutUndefined(values) {
|
|
58
|
+
const out = {};
|
|
59
|
+
for (const [key, value] of Object.entries(values)) {
|
|
60
|
+
if (value !== undefined)
|
|
61
|
+
out[key] = value;
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
async function answerTokenRequest(requestId) {
|
|
66
|
+
const provider = tokenProvider;
|
|
67
|
+
if (provider === null) {
|
|
68
|
+
NativeZellioChat_1.default.resolveToken(requestId, null, 'no_provider');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
let timer;
|
|
72
|
+
try {
|
|
73
|
+
const token = await Promise.race([
|
|
74
|
+
provider(),
|
|
75
|
+
new Promise((_, reject) => {
|
|
76
|
+
timer = setTimeout(() => reject(new Error('timeout')), exports.TOKEN_TIMEOUT_MS);
|
|
77
|
+
}),
|
|
78
|
+
]);
|
|
79
|
+
if (typeof token === 'string' && token.length > 0) {
|
|
80
|
+
NativeZellioChat_1.default.resolveToken(requestId, token, null);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
NativeZellioChat_1.default.resolveToken(requestId, null, 'no_token');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
const timedOut = error instanceof Error && error.message === 'timeout';
|
|
88
|
+
NativeZellioChat_1.default.resolveToken(requestId, null, timedOut ? 'timeout' : 'provider_error');
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
if (timer !== undefined)
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Marks a signed-in customer. `tokenProvider` returns a JWT from your server. The SDK calls it when it needs a
|
|
97
|
+
* session and again if the server rejects the token. The token is never logged. Calling `identify` again
|
|
98
|
+
* replaces the provider.
|
|
99
|
+
*/
|
|
100
|
+
function identify(provider) {
|
|
101
|
+
guard('identify', () => {
|
|
102
|
+
tokenProvider = provider;
|
|
103
|
+
if (tokenSubscription === null) {
|
|
104
|
+
tokenSubscription = NativeZellioChat_1.default.onTokenRequest((request) => {
|
|
105
|
+
void answerTokenRequest(request.requestId);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
NativeZellioChat_1.default.identify();
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/** Ends the session, deletes all local chat data and removes the push token from the server. */
|
|
112
|
+
function logout() {
|
|
113
|
+
guard('logout', () => {
|
|
114
|
+
tokenProvider = null;
|
|
115
|
+
NativeZellioChat_1.default.logout();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/** Shows chat on top of the app. */
|
|
119
|
+
function present() {
|
|
120
|
+
guard('present', () => NativeZellioChat_1.default.present());
|
|
121
|
+
}
|
|
122
|
+
/** Opens one conversation, or a new one when `conversationId` is omitted. */
|
|
123
|
+
function presentConversation(conversationId) {
|
|
124
|
+
guard('presentConversation', () => NativeZellioChat_1.default.presentConversation(conversationId ?? null));
|
|
125
|
+
}
|
|
126
|
+
/** Closes chat. */
|
|
127
|
+
function dismiss() {
|
|
128
|
+
guard('dismiss', () => NativeZellioChat_1.default.dismiss());
|
|
129
|
+
}
|
|
130
|
+
/** Tells agents what the customer looks at. It is sent with the next messages. `null` clears it. */
|
|
131
|
+
function setContext(context) {
|
|
132
|
+
guard('setContext', () => {
|
|
133
|
+
NativeZellioChat_1.default.setContext(context === null ? null : withoutUndefined({ ...context }));
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/** The number of unread agent messages, across all conversations. Resolves 0 if the SDK is not ready. */
|
|
137
|
+
async function getUnreadCount() {
|
|
138
|
+
try {
|
|
139
|
+
return await NativeZellioChat_1.default.getUnreadCount();
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
reportMisuse('getUnreadCount', error);
|
|
143
|
+
return 0;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** Calls back now with the current count and on every change. Call `remove()` to stop. */
|
|
147
|
+
function addUnreadListener(callback) {
|
|
148
|
+
let active = true;
|
|
149
|
+
const native = NativeZellioChat_1.default.onUnread((event) => {
|
|
150
|
+
if (active)
|
|
151
|
+
callback(event.count);
|
|
152
|
+
});
|
|
153
|
+
void getUnreadCount().then((count) => {
|
|
154
|
+
if (active)
|
|
155
|
+
callback(count);
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
remove() {
|
|
159
|
+
if (!active)
|
|
160
|
+
return;
|
|
161
|
+
active = false;
|
|
162
|
+
native.remove();
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/** Chat events for your own analytics. Call `remove()` to stop. */
|
|
167
|
+
function addEventListener(callback) {
|
|
168
|
+
const native = NativeZellioChat_1.default.onEvent((event) => {
|
|
169
|
+
switch (event.name) {
|
|
170
|
+
case 'chatOpened':
|
|
171
|
+
case 'chatClosed':
|
|
172
|
+
case 'messageSent':
|
|
173
|
+
case 'messageReceived':
|
|
174
|
+
callback({ type: event.name });
|
|
175
|
+
break;
|
|
176
|
+
case 'error':
|
|
177
|
+
callback({ type: 'error', code: event.code ?? 'unknown' });
|
|
178
|
+
break;
|
|
179
|
+
default:
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
return {
|
|
184
|
+
remove() {
|
|
185
|
+
native.remove();
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/** Gives the SDK the push token: the APNs token as a hex string on iOS, the FCM token on Android. */
|
|
190
|
+
function setPushToken(token, environment) {
|
|
191
|
+
guard('setPushToken', () => NativeZellioChat_1.default.setPushToken(token, environment ?? null));
|
|
192
|
+
}
|
|
193
|
+
function toJson(payload) {
|
|
194
|
+
if (payload === null || payload === undefined)
|
|
195
|
+
return null;
|
|
196
|
+
try {
|
|
197
|
+
return JSON.stringify(payload);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** True only if the payload has the `zellio` key. */
|
|
204
|
+
function isZellioPush(payload) {
|
|
205
|
+
const json = toJson(payload);
|
|
206
|
+
if (json === null)
|
|
207
|
+
return false;
|
|
208
|
+
try {
|
|
209
|
+
return NativeZellioChat_1.default.isZellioPush(json);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
reportMisuse('isZellioPush', error);
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** Refreshes the unread state. Resolves true if the push was ours. */
|
|
217
|
+
async function handlePush(payload) {
|
|
218
|
+
const json = toJson(payload);
|
|
219
|
+
if (json === null)
|
|
220
|
+
return false;
|
|
221
|
+
try {
|
|
222
|
+
return await NativeZellioChat_1.default.handlePush(json);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
reportMisuse('handlePush', error);
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/** Opens the conversation that the push names. Resolves true if the push was ours. */
|
|
230
|
+
async function handleNotificationTap(payload) {
|
|
231
|
+
const json = toJson(payload);
|
|
232
|
+
if (json === null)
|
|
233
|
+
return false;
|
|
234
|
+
try {
|
|
235
|
+
return await NativeZellioChat_1.default.handleNotificationTap(json);
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
reportMisuse('handleNotificationTap', error);
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type ZellioLocale = 'auto' | 'ar' | 'en';
|
|
2
|
+
export type ZellioThemeMode = 'auto' | 'light' | 'dark';
|
|
3
|
+
export type ZellioLogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug';
|
|
4
|
+
/** Colors are `#RRGGBB`. A color that would make text hard to read is adjusted by the native SDK. */
|
|
5
|
+
export interface ZellioTheme {
|
|
6
|
+
mode?: ZellioThemeMode;
|
|
7
|
+
primaryColor?: string;
|
|
8
|
+
customerMessageColor?: string;
|
|
9
|
+
surfaceColor?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ZellioChatConfig {
|
|
12
|
+
/** The app key from Zellio Studio. */
|
|
13
|
+
appKey: string;
|
|
14
|
+
/** Default: https://app.zellio.ai */
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
/** Default: `auto` (the Studio language policy, then the device language). */
|
|
17
|
+
locale?: ZellioLocale;
|
|
18
|
+
theme?: ZellioTheme;
|
|
19
|
+
/** Default: `error` on iOS and `warn` on Android. Chat text and tokens are never logged. */
|
|
20
|
+
logLevel?: ZellioLogLevel;
|
|
21
|
+
/** The small banner for a new message while chat is closed. Default: true. */
|
|
22
|
+
showsInAppBanner?: boolean;
|
|
23
|
+
/** false: the banner says "New message" and never shows the text. Default: true. */
|
|
24
|
+
bannerShowsPreview?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** What the customer is looking at. Agents see it. `url` must be https. */
|
|
27
|
+
export interface ZellioContext {
|
|
28
|
+
screen?: string;
|
|
29
|
+
itemType?: string;
|
|
30
|
+
itemId?: string;
|
|
31
|
+
itemTitle?: string;
|
|
32
|
+
url?: string;
|
|
33
|
+
}
|
|
34
|
+
/** Events for your own analytics. They never carry message text. */
|
|
35
|
+
export type ZellioChatEvent = {
|
|
36
|
+
type: 'chatOpened';
|
|
37
|
+
} | {
|
|
38
|
+
type: 'chatClosed';
|
|
39
|
+
} | {
|
|
40
|
+
type: 'messageSent';
|
|
41
|
+
} | {
|
|
42
|
+
type: 'messageReceived';
|
|
43
|
+
} | {
|
|
44
|
+
type: 'error';
|
|
45
|
+
code: string;
|
|
46
|
+
};
|
|
47
|
+
/** Returns the identity JWT from your server, or null when nobody is signed in. */
|
|
48
|
+
export type ZellioTokenProvider = () => Promise<string | null>;
|
|
49
|
+
export interface ZellioSubscription {
|
|
50
|
+
remove(): void;
|
|
51
|
+
}
|
|
52
|
+
export type ZellioPushEnvironment = 'sandbox' | 'production';
|
|
53
|
+
/** The data of a push message, as your push library gives it to you. */
|
|
54
|
+
export type ZellioPushPayload = Record<string, unknown>;
|
package/lib/types.js
ADDED
package/lib/version.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Kept equal to package.json by `npm run check:version` (runs before every pack). */
|
|
2
|
+
export declare const VERSION = "1.0.0";
|
|
3
|
+
/** Sent to the native SDK as `wrapper`, so the x-zee-sdk-wrapper header names this package. */
|
|
4
|
+
export declare const WRAPPER = "react-native/1.0.0";
|
package/lib/version.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WRAPPER = exports.VERSION = void 0;
|
|
4
|
+
/** Kept equal to package.json by `npm run check:version` (runs before every pack). */
|
|
5
|
+
exports.VERSION = '1.0.0';
|
|
6
|
+
/** Sent to the native SDK as `wrapper`, so the x-zee-sdk-wrapper header names this package. */
|
|
7
|
+
exports.WRAPPER = `react-native/${exports.VERSION}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,77 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zellio/chat-react-native",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ZeeChat for React Native: a thin wrapper over the native Zellio chat SDKs for iOS and Android.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://zellio.ai",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/zellio-ai/zellio-chat-sdk.git",
|
|
10
|
+
"directory": "react-native"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/zellio-ai/zellio-chat-sdk/issues"
|
|
14
|
+
},
|
|
15
|
+
"main": "lib/index.js",
|
|
16
|
+
"types": "lib/index.d.ts",
|
|
17
|
+
"react-native": "src/index.ts",
|
|
18
|
+
"source": "src/index.ts",
|
|
19
|
+
"files": [
|
|
20
|
+
"lib",
|
|
21
|
+
"src",
|
|
22
|
+
"android",
|
|
23
|
+
"ios",
|
|
24
|
+
"plugin/build",
|
|
25
|
+
"app.plugin.js",
|
|
26
|
+
"ZellioChatReactNative.podspec",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE",
|
|
29
|
+
"!**/__tests__",
|
|
30
|
+
"!android/build",
|
|
31
|
+
"!android/.gradle",
|
|
32
|
+
"!ios/build"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc -p tsconfig.build.json && tsc -p plugin/tsconfig.json",
|
|
36
|
+
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p plugin/tsconfig.json",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"vendor:ios": "node scripts/vendor-ios.mjs",
|
|
39
|
+
"check:version": "node scripts/check-version.mjs",
|
|
40
|
+
"prepack": "node scripts/check-version.mjs && node scripts/vendor-ios.mjs && npm run build",
|
|
41
|
+
"ci": "bash scripts/ci-check.sh"
|
|
42
|
+
},
|
|
43
|
+
"codegenConfig": {
|
|
44
|
+
"name": "RNZellioChatSpec",
|
|
45
|
+
"type": "modules",
|
|
46
|
+
"jsSrcsDir": "src",
|
|
47
|
+
"android": {
|
|
48
|
+
"javaPackageName": "ai.zellio.chat.reactnative"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"expo": ">=58",
|
|
53
|
+
"react": ">=19.1",
|
|
54
|
+
"react-native": ">=0.82"
|
|
55
|
+
},
|
|
56
|
+
"peerDependenciesMeta": {
|
|
57
|
+
"expo": {
|
|
58
|
+
"optional": true
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/node": "^22.0.0",
|
|
63
|
+
"@types/react": "~19.3.0",
|
|
64
|
+
"expo": "~58.0.22",
|
|
65
|
+
"react": "19.3.0",
|
|
66
|
+
"react-native": "0.88.1",
|
|
67
|
+
"typescript": "~6.0.2",
|
|
68
|
+
"vitest": "^4.1.11"
|
|
69
|
+
},
|
|
70
|
+
"overrides": {
|
|
71
|
+
"glob": "^14.0.2",
|
|
72
|
+
"minimatch": "^11.0.1"
|
|
73
|
+
},
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_PHOTO_TEXT = exports.DEFAULT_CAMERA_TEXT = void 0;
|
|
4
|
+
exports.applyInfoPlist = applyInfoPlist;
|
|
5
|
+
exports.applyEntitlements = applyEntitlements;
|
|
6
|
+
exports.applyMavenRepository = applyMavenRepository;
|
|
7
|
+
const config_plugins_1 = require("expo/config-plugins");
|
|
8
|
+
exports.DEFAULT_CAMERA_TEXT = 'Allow $(PRODUCT_NAME) to use the camera so you can send photos in chat.';
|
|
9
|
+
exports.DEFAULT_PHOTO_TEXT = 'Allow $(PRODUCT_NAME) to access your photos so you can send them in chat.';
|
|
10
|
+
/** Adds the usage texts. A key that the app already sets is never replaced. */
|
|
11
|
+
function applyInfoPlist(plist, props) {
|
|
12
|
+
const out = { ...plist };
|
|
13
|
+
if (props.cameraPermission !== false && out.NSCameraUsageDescription === undefined) {
|
|
14
|
+
out.NSCameraUsageDescription = props.cameraPermission ?? exports.DEFAULT_CAMERA_TEXT;
|
|
15
|
+
}
|
|
16
|
+
if (props.photoLibraryPermission !== false && out.NSPhotoLibraryUsageDescription === undefined) {
|
|
17
|
+
out.NSPhotoLibraryUsageDescription = props.photoLibraryPermission ?? exports.DEFAULT_PHOTO_TEXT;
|
|
18
|
+
}
|
|
19
|
+
if (props.enableIosPush === true) {
|
|
20
|
+
const modes = Array.isArray(out.UIBackgroundModes) ? [...out.UIBackgroundModes] : [];
|
|
21
|
+
if (!modes.includes('remote-notification'))
|
|
22
|
+
modes.push('remote-notification');
|
|
23
|
+
out.UIBackgroundModes = modes;
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
/** Push entitlement. Only when asked. */
|
|
28
|
+
function applyEntitlements(entitlements, props) {
|
|
29
|
+
if (props.enableIosPush !== true)
|
|
30
|
+
return entitlements;
|
|
31
|
+
if (entitlements['aps-environment'] !== undefined)
|
|
32
|
+
return entitlements;
|
|
33
|
+
return { ...entitlements, 'aps-environment': props.apsEnvironment ?? 'development' };
|
|
34
|
+
}
|
|
35
|
+
const MARKER = '// @zellio/chat-react-native';
|
|
36
|
+
/** Adds a Maven repository to `allprojects.repositories`. Safe to run twice. */
|
|
37
|
+
function applyMavenRepository(gradle, url) {
|
|
38
|
+
if (gradle.includes(MARKER))
|
|
39
|
+
return gradle;
|
|
40
|
+
const pattern = /allprojects\s*\{\s*repositories\s*\{/;
|
|
41
|
+
if (!pattern.test(gradle)) {
|
|
42
|
+
throw new Error('@zellio/chat-react-native: could not find allprojects { repositories { in android/build.gradle. ' +
|
|
43
|
+
`Add maven { url '${url}' } by hand.`);
|
|
44
|
+
}
|
|
45
|
+
const safe = url.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
46
|
+
return gradle.replace(pattern, (match) => `${match}\n maven { url '${safe}' } ${MARKER}`);
|
|
47
|
+
}
|
|
48
|
+
const withZellioChat = (config, props) => {
|
|
49
|
+
const options = props ?? {};
|
|
50
|
+
config = (0, config_plugins_1.withInfoPlist)(config, (mod) => {
|
|
51
|
+
mod.modResults = applyInfoPlist(mod.modResults, options);
|
|
52
|
+
return mod;
|
|
53
|
+
});
|
|
54
|
+
if (options.enableIosPush === true) {
|
|
55
|
+
config = (0, config_plugins_1.withEntitlementsPlist)(config, (mod) => {
|
|
56
|
+
mod.modResults = applyEntitlements(mod.modResults, options);
|
|
57
|
+
return mod;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (options.androidMavenRepository) {
|
|
61
|
+
const url = options.androidMavenRepository;
|
|
62
|
+
config = (0, config_plugins_1.withProjectBuildGradle)(config, (mod) => {
|
|
63
|
+
if (mod.modResults.language !== 'groovy') {
|
|
64
|
+
throw new Error('@zellio/chat-react-native: androidMavenRepository needs a Groovy android/build.gradle.');
|
|
65
|
+
}
|
|
66
|
+
mod.modResults.contents = applyMavenRepository(mod.modResults.contents, url);
|
|
67
|
+
return mod;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return config;
|
|
71
|
+
};
|
|
72
|
+
const pkg = require('../../package.json');
|
|
73
|
+
exports.default = (0, config_plugins_1.createRunOncePlugin)(withZellioChat, pkg.name, pkg.version);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CodegenTypes, TurboModule } from 'react-native';
|
|
2
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Codegen spec. Do not import this file from app code: use the typed API in `index.ts`.
|
|
6
|
+
* Options travel as plain objects so the generated native code stays small; `index.ts` types them.
|
|
7
|
+
*/
|
|
8
|
+
export interface Spec extends TurboModule {
|
|
9
|
+
configure(appKey: string, options: CodegenTypes.UnsafeObject): void;
|
|
10
|
+
/** Registers the token provider on the native side. Native then asks JS through `onTokenRequest`. */
|
|
11
|
+
identify(): void;
|
|
12
|
+
/** Answers one `onTokenRequest`. Exactly one of `token` and `errorCode` is set. */
|
|
13
|
+
resolveToken(requestId: string, token: string | null, errorCode: string | null): void;
|
|
14
|
+
logout(): void;
|
|
15
|
+
present(): void;
|
|
16
|
+
presentConversation(conversationId: string | null): void;
|
|
17
|
+
dismiss(): void;
|
|
18
|
+
setContext(context: CodegenTypes.UnsafeObject | null): void;
|
|
19
|
+
getUnreadCount(): Promise<number>;
|
|
20
|
+
setPushToken(token: string, environment: string | null): void;
|
|
21
|
+
isZellioPush(payloadJson: string): boolean;
|
|
22
|
+
handlePush(payloadJson: string): Promise<boolean>;
|
|
23
|
+
handleNotificationTap(payloadJson: string): Promise<boolean>;
|
|
24
|
+
|
|
25
|
+
readonly onUnread: CodegenTypes.EventEmitter<{ count: number }>;
|
|
26
|
+
readonly onEvent: CodegenTypes.EventEmitter<{ name: string; code?: string }>;
|
|
27
|
+
readonly onTokenRequest: CodegenTypes.EventEmitter<{ requestId: string }>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('RNZellioChat');
|