@rematter/pylon-react-native 0.1.4
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/README.md +503 -0
- package/RNPylonChat.podspec +33 -0
- package/android/build.gradle +74 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/pylon/chatwidget/Pylon.kt +149 -0
- package/android/src/main/java/com/pylon/chatwidget/PylonChat.kt +715 -0
- package/android/src/main/java/com/pylon/chatwidget/PylonChatController.kt +63 -0
- package/android/src/main/java/com/pylon/chatwidget/PylonChatListener.kt +76 -0
- package/android/src/main/java/com/pylon/chatwidget/PylonChatView.kt +7 -0
- package/android/src/main/java/com/pylon/chatwidget/PylonConfig.kt +62 -0
- package/android/src/main/java/com/pylon/chatwidget/PylonDebugView.kt +76 -0
- package/android/src/main/java/com/pylon/chatwidget/PylonUser.kt +41 -0
- package/android/src/main/java/com/pylonchat/reactnative/RNPylonChatPackage.kt +17 -0
- package/android/src/main/java/com/pylonchat/reactnative/RNPylonChatView.kt +298 -0
- package/android/src/main/java/com/pylonchat/reactnative/RNPylonChatViewManager.kt +201 -0
- package/ios/PylonChat/PylonChat.swift +865 -0
- package/ios/RNPylonChatView.swift +332 -0
- package/ios/RNPylonChatViewManager.m +55 -0
- package/ios/RNPylonChatViewManager.swift +23 -0
- package/lib/PylonChatView.d.ts +27 -0
- package/lib/PylonChatView.js +78 -0
- package/lib/PylonChatWidget.android.d.ts +19 -0
- package/lib/PylonChatWidget.android.js +144 -0
- package/lib/PylonChatWidget.ios.d.ts +14 -0
- package/lib/PylonChatWidget.ios.js +79 -0
- package/lib/PylonModule.d.ts +32 -0
- package/lib/PylonModule.js +44 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +15 -0
- package/lib/types.d.ts +34 -0
- package/lib/types.js +2 -0
- package/package.json +39 -0
- package/src/PylonChatView.tsx +170 -0
- package/src/PylonChatWidget.android.tsx +165 -0
- package/src/PylonChatWidget.d.ts +15 -0
- package/src/PylonChatWidget.ios.tsx +79 -0
- package/src/PylonModule.ts +52 -0
- package/src/index.ts +15 -0
- package/src/types.ts +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
# Pylon Chat SDK for React Native
|
|
2
|
+
|
|
3
|
+
Add Pylon's chat widget to your React Native application to enable in-app customer support.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- React Native >= 0.70.0
|
|
8
|
+
- iOS >= 13.0
|
|
9
|
+
- Android minSdkVersion >= 24
|
|
10
|
+
|
|
11
|
+
**Note:** This package uses native modules. For Expo projects, you'll need a [development build](https://docs.expo.dev/develop/development-builds/introduction/).
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
This SDK is distributed as source code and installed from a local directory.
|
|
18
|
+
|
|
19
|
+
### Step 1: Clone the Repository
|
|
20
|
+
|
|
21
|
+
Clone the SDK repository anywhere on your machine, but preferably forked into your own repository:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
git clone https://github.com/pylon-labs/sdk-mobile.git
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Step 2: Install the Package
|
|
28
|
+
|
|
29
|
+
From your React Native project root, install from the local path:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install /path/to/sdk-mobile/react-native
|
|
33
|
+
# or
|
|
34
|
+
yarn add file:/path/to/sdk-mobile/react-native
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**What happens automatically:**
|
|
38
|
+
|
|
39
|
+
- npm runs the `prepare` script (compiles TypeScript, copies native code)
|
|
40
|
+
- Package is installed to `node_modules/@pylon/react-native-chat/`
|
|
41
|
+
|
|
42
|
+
### Step 3: Link Native Code
|
|
43
|
+
|
|
44
|
+
The SDK includes native Swift (iOS) and Kotlin (Android) code that needs to be linked to your app.
|
|
45
|
+
|
|
46
|
+
**For Expo projects:**
|
|
47
|
+
|
|
48
|
+
Expo apps don't have native folders by default. Generate them:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx expo install expo-dev-client
|
|
52
|
+
npx expo prebuild
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This creates `ios/` and `android/` folders with the SDK's native code linked.
|
|
56
|
+
|
|
57
|
+
**For bare React Native projects:**
|
|
58
|
+
|
|
59
|
+
iOS requires CocoaPods linking:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cd ios && pod install && cd ..
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Android auto-links automatically (no action needed).
|
|
66
|
+
|
|
67
|
+
### Step 4: Get Your Pylon App ID
|
|
68
|
+
|
|
69
|
+
1. Login to [app.usepylon.com](https://app.usepylon.com)
|
|
70
|
+
2. Go to Settings → Chat Widget
|
|
71
|
+
3. Copy your App ID
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Quick Start
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { PylonChatView, type PylonChatViewRef } from "@pylon/react-native-chat";
|
|
79
|
+
import { useRef } from "react";
|
|
80
|
+
import { StyleSheet, View } from "react-native";
|
|
81
|
+
|
|
82
|
+
export default function App() {
|
|
83
|
+
const pylonRef = useRef<PylonChatViewRef>(null);
|
|
84
|
+
|
|
85
|
+
const config = {
|
|
86
|
+
appId: "YOUR_APP_ID", // Get from app.usepylon.com/settings/chat-widget
|
|
87
|
+
widgetBaseUrl: "https://widget.usepylon.com",
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const user = {
|
|
91
|
+
email: "user@example.com",
|
|
92
|
+
name: "User Name",
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<View style={styles.container}>
|
|
97
|
+
{/* Your app content */}
|
|
98
|
+
<Text>My App Content</Text>
|
|
99
|
+
|
|
100
|
+
{/* Pylon Chat Widget - renders as overlay */}
|
|
101
|
+
<PylonChatView
|
|
102
|
+
ref={pylonRef}
|
|
103
|
+
config={config}
|
|
104
|
+
user={user}
|
|
105
|
+
style={styles.chat}
|
|
106
|
+
/>
|
|
107
|
+
</View>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const styles = StyleSheet.create({
|
|
112
|
+
container: {
|
|
113
|
+
flex: 1,
|
|
114
|
+
},
|
|
115
|
+
chat: {
|
|
116
|
+
position: "absolute",
|
|
117
|
+
top: 0,
|
|
118
|
+
left: 0,
|
|
119
|
+
right: 0,
|
|
120
|
+
bottom: 0,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Identity Verification (Strongly Recommended):**
|
|
126
|
+
|
|
127
|
+
We strongly recommend setting up [Identity Verification](https://docs.usepylon.com/pylon-docs/chat-widget/identity-verification). The `emailHash` needs to be generated by the server responsible for authorizing your mobile app.
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
const user = {
|
|
131
|
+
email: "user@example.com",
|
|
132
|
+
name: "User Name",
|
|
133
|
+
emailHash: "sha256_hash_generated_by_server", // Add this for identity verification
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## API Reference
|
|
140
|
+
|
|
141
|
+
### PylonChatView Props
|
|
142
|
+
|
|
143
|
+
#### `config` (required)
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
{
|
|
147
|
+
appId: string; // Your Pylon app ID (required)
|
|
148
|
+
widgetBaseUrl?: string; // Default: "https://widget.usepylon.com"
|
|
149
|
+
enableLogging?: boolean; // Enable debug logs (default: false)
|
|
150
|
+
debugMode?: boolean; // Show debug overlay (default: false)
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### `user` (required)
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
{
|
|
158
|
+
email: string; // User's email (required)
|
|
159
|
+
name: string; // User's name (required)
|
|
160
|
+
avatarUrl?: string; // User's avatar URL
|
|
161
|
+
emailHash?: string; // SHA-256 hash for identity verification
|
|
162
|
+
accountId?: string; // Your internal account ID
|
|
163
|
+
accountExternalId?: string; // External system account ID
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### `listener` (optional)
|
|
168
|
+
|
|
169
|
+
Event callbacks for chat interactions:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
{
|
|
173
|
+
onPylonLoaded?: () => void;
|
|
174
|
+
onPylonInitialized?: () => void;
|
|
175
|
+
onPylonReady?: () => void;
|
|
176
|
+
onChatOpened?: () => void;
|
|
177
|
+
onChatClosed?: (wasOpen: boolean) => void;
|
|
178
|
+
onUnreadCountChanged?: (count: number) => void;
|
|
179
|
+
onMessageReceived?: (message: string) => void;
|
|
180
|
+
onPylonError?: (error: string) => void;
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### `style` (optional)
|
|
185
|
+
|
|
186
|
+
Standard React Native `ViewStyle`. Typically used to position the widget:
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
style={{
|
|
190
|
+
position: "absolute",
|
|
191
|
+
top: 0,
|
|
192
|
+
left: 0,
|
|
193
|
+
right: 0,
|
|
194
|
+
bottom: 0,
|
|
195
|
+
}}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### Imperative Methods (via ref)
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
const pylonRef = useRef<PylonChatViewRef>(null);
|
|
204
|
+
|
|
205
|
+
// Control chat window
|
|
206
|
+
pylonRef.current?.openChat();
|
|
207
|
+
pylonRef.current?.closeChat();
|
|
208
|
+
|
|
209
|
+
// Control chat bubble
|
|
210
|
+
pylonRef.current?.showChatBubble();
|
|
211
|
+
pylonRef.current?.hideChatBubble();
|
|
212
|
+
|
|
213
|
+
// Send messages programmatically
|
|
214
|
+
pylonRef.current?.showNewMessage("Hello from the app!", false);
|
|
215
|
+
pylonRef.current?.showNewMessage("<p><strong>HTML</strong> message</p>", true);
|
|
216
|
+
|
|
217
|
+
// Set custom fields for new issues
|
|
218
|
+
pylonRef.current?.setNewIssueCustomFields({
|
|
219
|
+
source: "mobile-app",
|
|
220
|
+
version: "1.2.3",
|
|
221
|
+
platform: Platform.OS,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Show specific forms
|
|
225
|
+
pylonRef.current?.showTicketForm("form-id");
|
|
226
|
+
pylonRef.current?.showKnowledgeBaseArticle("article-id");
|
|
227
|
+
|
|
228
|
+
// Pre-fill ticket form fields
|
|
229
|
+
pylonRef.current?.setTicketFormFields({
|
|
230
|
+
subject: "Issue from mobile app",
|
|
231
|
+
description: "User reported...",
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Identity verification
|
|
235
|
+
pylonRef.current?.updateEmailHash("sha256_hash");
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Usage Patterns
|
|
241
|
+
|
|
242
|
+
### Basic Setup with Event Listeners
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
export default function App() {
|
|
246
|
+
const pylonRef = useRef<PylonChatViewRef>(null);
|
|
247
|
+
const [unreadCount, setUnreadCount] = useState(0);
|
|
248
|
+
|
|
249
|
+
const config = {
|
|
250
|
+
appId: "YOUR_APP_ID",
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const user = {
|
|
254
|
+
email: "user@example.com",
|
|
255
|
+
name: "User Name",
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const listener = {
|
|
259
|
+
onChatOpened: () => console.log("Chat opened"),
|
|
260
|
+
onChatClosed: (wasOpen) => console.log("Chat closed", wasOpen),
|
|
261
|
+
onUnreadCountChanged: (count) => setUnreadCount(count),
|
|
262
|
+
onMessageReceived: (msg) => console.log("New message:", msg),
|
|
263
|
+
onPylonError: (error) => console.error("Pylon error:", error),
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<View style={{ flex: 1 }}>
|
|
268
|
+
<MyAppContent />
|
|
269
|
+
|
|
270
|
+
{unreadCount > 0 && <Badge count={unreadCount} />}
|
|
271
|
+
|
|
272
|
+
<PylonChatView
|
|
273
|
+
ref={pylonRef}
|
|
274
|
+
config={config}
|
|
275
|
+
user={user}
|
|
276
|
+
listener={listener}
|
|
277
|
+
style={StyleSheet.absoluteFill}
|
|
278
|
+
/>
|
|
279
|
+
</View>
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### With Safe Area Insets
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
288
|
+
|
|
289
|
+
export default function App() {
|
|
290
|
+
const insets = useSafeAreaInsets();
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
<View style={{ flex: 1 }}>
|
|
294
|
+
<MyAppContent />
|
|
295
|
+
|
|
296
|
+
<PylonChatView
|
|
297
|
+
config={config}
|
|
298
|
+
user={user}
|
|
299
|
+
style={{
|
|
300
|
+
position: "absolute",
|
|
301
|
+
top: 0,
|
|
302
|
+
left: 0,
|
|
303
|
+
right: 0,
|
|
304
|
+
bottom: 0,
|
|
305
|
+
paddingTop: insets.top,
|
|
306
|
+
paddingBottom: insets.bottom,
|
|
307
|
+
}}
|
|
308
|
+
/>
|
|
309
|
+
</View>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Conditional Rendering (User Login)
|
|
315
|
+
|
|
316
|
+
```tsx
|
|
317
|
+
export default function App() {
|
|
318
|
+
const [currentUser, setCurrentUser] = useState(null);
|
|
319
|
+
|
|
320
|
+
return (
|
|
321
|
+
<View style={{ flex: 1 }}>
|
|
322
|
+
<MyAppContent />
|
|
323
|
+
|
|
324
|
+
{currentUser && (
|
|
325
|
+
<PylonChatView
|
|
326
|
+
config={{ appId: "YOUR_APP_ID" }}
|
|
327
|
+
user={{
|
|
328
|
+
email: currentUser.email,
|
|
329
|
+
name: currentUser.name,
|
|
330
|
+
}}
|
|
331
|
+
style={StyleSheet.absoluteFill}
|
|
332
|
+
/>
|
|
333
|
+
)}
|
|
334
|
+
</View>
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Custom Fields and Metadata
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
export default function App() {
|
|
343
|
+
const pylonRef = useRef<PylonChatViewRef>(null);
|
|
344
|
+
|
|
345
|
+
useEffect(() => {
|
|
346
|
+
// Set custom fields when component mounts
|
|
347
|
+
pylonRef.current?.setNewIssueCustomFields({
|
|
348
|
+
app_version: "1.2.3",
|
|
349
|
+
platform: Platform.OS,
|
|
350
|
+
device_model: DeviceInfo.getModel(),
|
|
351
|
+
user_tier: "premium",
|
|
352
|
+
});
|
|
353
|
+
}, []);
|
|
354
|
+
|
|
355
|
+
return (
|
|
356
|
+
<View style={{ flex: 1 }}>
|
|
357
|
+
<MyAppContent />
|
|
358
|
+
<PylonChatView
|
|
359
|
+
ref={pylonRef}
|
|
360
|
+
config={config}
|
|
361
|
+
user={user}
|
|
362
|
+
style={StyleSheet.absoluteFill}
|
|
363
|
+
/>
|
|
364
|
+
</View>
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Known Limitations
|
|
372
|
+
|
|
373
|
+
### Android: Clickable Elements in Chat Widget
|
|
374
|
+
|
|
375
|
+
**Issue:** On Android React Native specifically, clickable elements associated with an unopened chat widget (such as surveys) besides the chat bubble do not currently work. The chat bubble itself functions correctly for opening and closing the widget.
|
|
376
|
+
|
|
377
|
+
**Workaround:** This is a known platform limitation related to touch event handling between React Native and Android.
|
|
378
|
+
|
|
379
|
+
**Need this functionality?** Please contact the Pylon team if your application requires interactive elements like surveys in the Android React Native chat widget. We'd love to hear about your use case and prioritize a smarter React Native Android touch handler.
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Troubleshooting
|
|
384
|
+
|
|
385
|
+
### Android: Java Version Issues
|
|
386
|
+
|
|
387
|
+
**Error:** `Unsupported class file major version 69`
|
|
388
|
+
|
|
389
|
+
**Solution:** Install Java 17:
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
brew install openjdk@17
|
|
393
|
+
export JAVA_HOME=$(/usr/libexec/java_home -v 17)
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### iOS: CocoaPods Encoding Issues
|
|
397
|
+
|
|
398
|
+
**Error:** `Unicode Normalization not appropriate for ASCII-8BIT`
|
|
399
|
+
|
|
400
|
+
**Solution:**
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
export LANG=en_US.UTF-8
|
|
404
|
+
cd ios && pod install
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Expo: Development Build Required
|
|
408
|
+
|
|
409
|
+
**Error:** `No development build installed`
|
|
410
|
+
|
|
411
|
+
**Solution:** This package uses native modules and cannot run in Expo Go:
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
npx expo install expo-dev-client
|
|
415
|
+
npx expo prebuild
|
|
416
|
+
npx expo run:ios # or expo run:android
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Module Not Found
|
|
420
|
+
|
|
421
|
+
**Error:** `Invariant Violation: View config not found for component RNPylonChatView`
|
|
422
|
+
|
|
423
|
+
**Solution:** Clean and rebuild:
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
# Expo
|
|
427
|
+
rm -rf ios android .expo
|
|
428
|
+
npx expo prebuild --clean
|
|
429
|
+
npx expo run:ios
|
|
430
|
+
|
|
431
|
+
# Bare React Native
|
|
432
|
+
cd ios && pod install && cd ..
|
|
433
|
+
npx react-native run-ios
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Touch Events Not Working
|
|
437
|
+
|
|
438
|
+
If touches aren't passing through to views behind the chat bubble:
|
|
439
|
+
|
|
440
|
+
1. Use `position: "absolute"` and cover the full screen
|
|
441
|
+
2. Don't wrap `PylonChatView` in additional Views that intercept touches
|
|
442
|
+
3. The native SDK handles touch pass-through automatically
|
|
443
|
+
|
|
444
|
+
```tsx
|
|
445
|
+
// ✅ Correct
|
|
446
|
+
<View style={{ flex: 1 }}>
|
|
447
|
+
<ScrollView>{/* Your content */}</ScrollView>
|
|
448
|
+
<PylonChatView style={StyleSheet.absoluteFill} {...props} />
|
|
449
|
+
</View>
|
|
450
|
+
|
|
451
|
+
// ❌ Wrong - extra wrapper intercepts touches
|
|
452
|
+
<View style={{ flex: 1 }}>
|
|
453
|
+
<ScrollView>{/* Your content */}</ScrollView>
|
|
454
|
+
<View style={StyleSheet.absoluteFill}>
|
|
455
|
+
<PylonChatView style={{ flex: 1 }} {...props} />
|
|
456
|
+
</View>
|
|
457
|
+
</View>
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## Architecture
|
|
463
|
+
|
|
464
|
+
This package wraps the native iOS and Android Pylon Chat SDKs using React Native's native module system:
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
468
|
+
│ React Native (JavaScript/TypeScript) │
|
|
469
|
+
│ <PylonChatView /> │
|
|
470
|
+
└───────────────────────┬─────────────────────────────────────┘
|
|
471
|
+
│ Native Bridge
|
|
472
|
+
┌───────────────────────▼─────────────────────────────────────┐
|
|
473
|
+
│ Native Module (iOS: Swift, Android: Kotlin) │
|
|
474
|
+
│ - RNPylonChatView.swift / RNPylonChatView.kt │
|
|
475
|
+
│ - Props → Native config conversion │
|
|
476
|
+
│ - Event forwarding to JS │
|
|
477
|
+
└───────────────────────┬─────────────────────────────────────┘
|
|
478
|
+
│
|
|
479
|
+
┌───────────────────────▼─────────────────────────────────────┐
|
|
480
|
+
│ Native SDK (PylonChat) │
|
|
481
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
482
|
+
│ │ WebView (Pylon Chat Widget) │ │
|
|
483
|
+
│ │ - Loads from widget.usepylon.com │ │
|
|
484
|
+
│ │ - JavaScript ↔ Native bridge │ │
|
|
485
|
+
│ │ - Touch pass-through when collapsed │ │
|
|
486
|
+
│ │ - Real-time messaging │ │
|
|
487
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
488
|
+
└─────────────────────────────────────────────────────────────┘
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
The widget is WebView-based, providing consistent functionality with the web SDK while native code handles platform-specific integration.
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Demo App
|
|
496
|
+
|
|
497
|
+
See [`demo-app/README.md`](./demo-app/README.md) for a complete example application demonstrating all SDK features.
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
## Support
|
|
502
|
+
|
|
503
|
+
For issues or questions, please reach out to the Pylon team.
|
|
@@ -0,0 +1,33 @@
|
|
|
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 = "RNPylonChat"
|
|
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 => "13.0" }
|
|
14
|
+
s.source = { :git => "https://github.com/usepylon/pylon-chat-sdk.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
# Bridge files + Copied iOS SDK
|
|
17
|
+
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
18
|
+
|
|
19
|
+
# Exclude demo apps
|
|
20
|
+
s.exclude_files = [
|
|
21
|
+
"demo-app/**/*",
|
|
22
|
+
"../ios/DemoApp/**/*"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
s.requires_arc = true
|
|
26
|
+
s.swift_version = "5.0"
|
|
27
|
+
|
|
28
|
+
s.dependency "React-Core"
|
|
29
|
+
|
|
30
|
+
# WebKit is required by PylonChat SDK
|
|
31
|
+
s.frameworks = "WebKit"
|
|
32
|
+
end
|
|
33
|
+
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.kotlin_version = '1.9.0'
|
|
3
|
+
repositories {
|
|
4
|
+
google()
|
|
5
|
+
mavenCentral()
|
|
6
|
+
}
|
|
7
|
+
dependencies {
|
|
8
|
+
classpath 'com.android.tools.build:gradle:8.0.2'
|
|
9
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
apply plugin: 'com.android.library'
|
|
14
|
+
apply plugin: 'kotlin-android'
|
|
15
|
+
|
|
16
|
+
def getExtOrDefault(name) {
|
|
17
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['RNPylonChat_' + name]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
def getExtOrIntegerDefault(name) {
|
|
21
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['RNPylonChat_' + name]).toInteger()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
android {
|
|
25
|
+
namespace "com.pylonchat.reactnative"
|
|
26
|
+
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
|
27
|
+
|
|
28
|
+
defaultConfig {
|
|
29
|
+
minSdkVersion getExtOrIntegerDefault('minSdkVersion')
|
|
30
|
+
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
|
|
31
|
+
versionCode 1
|
|
32
|
+
versionName "1.0"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
buildTypes {
|
|
36
|
+
release {
|
|
37
|
+
minifyEnabled false
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
lintOptions {
|
|
42
|
+
disable 'GradleCompatible'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
compileOptions {
|
|
46
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
47
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
kotlinOptions {
|
|
51
|
+
jvmTarget = '17'
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Source sets now include copied SDK files
|
|
55
|
+
sourceSets {
|
|
56
|
+
main {
|
|
57
|
+
java.srcDirs = ['src/main/java']
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
repositories {
|
|
63
|
+
mavenCentral()
|
|
64
|
+
google()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
dependencies {
|
|
68
|
+
implementation 'com.facebook.react:react-android'
|
|
69
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
70
|
+
|
|
71
|
+
// WebView dependency (same as parent SDK)
|
|
72
|
+
implementation 'androidx.webkit:webkit:1.8.0'
|
|
73
|
+
}
|
|
74
|
+
|