rns-nativecall 1.3.0 โ 1.3.2
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 +108 -74
- package/package.json +6 -3
- package/withNativeCallVoip.js +1 -0
package/README.md
CHANGED
|
@@ -1,31 +1,43 @@
|
|
|
1
1
|
# rns-nativecall
|
|
2
2
|
|
|
3
|
-
A professional VoIP incoming call handler for React Native
|
|
3
|
+
A **professional VoIP incoming call handler for React Native** with full **Android & iOS native UI integration**.
|
|
4
|
+
Designed for production-grade apps requiring **CallKit**, **lockscreen handling**, **headless execution**, and **single-call enforcement**.
|
|
5
|
+
|
|
6
|
+
---
|
|
4
7
|
|
|
5
8
|
## ๐ Highlights
|
|
6
|
-
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
+
|
|
10
|
+
- ๐ฆ **Expo Ready** โ Zero manual native setup via config plugin
|
|
11
|
+
- โ๏ธ **Single Call Gate** โ Automatically blocks concurrent calls and emits `BUSY` events
|
|
12
|
+
- ๐ง **Headless Mode** โ Works when the app is killed, backgrounded, or screen locked
|
|
13
|
+
- ๐ฑ **Native UI** โ Full-screen Android Activity & iOS CallKit
|
|
14
|
+
- ๐ **System-Level Reliability** โ No JS race conditions, no ghost calls
|
|
9
15
|
|
|
10
16
|
---
|
|
11
17
|
|
|
12
18
|
## ๐ฆ Installation
|
|
13
19
|
|
|
14
20
|
```bash
|
|
15
|
-
npx expo install rns-nativecall expo-build-properties
|
|
16
|
-
|
|
21
|
+
npx expo install rns-nativecall expo-build-properties react-native-uuid
|
|
17
22
|
```
|
|
23
|
+
|
|
18
24
|
or
|
|
19
|
-
```bash
|
|
20
|
-
npm install rns-nativecall expo-build-properties
|
|
21
25
|
|
|
26
|
+
```bash
|
|
27
|
+
npm install rns-nativecall expo-build-properties react-native-uuid
|
|
22
28
|
```
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## โ๏ธ Expo Configuration
|
|
33
|
+
|
|
34
|
+
Add the plugin to **app.json** or **app.config.js**:
|
|
35
|
+
|
|
25
36
|
```json
|
|
26
37
|
{
|
|
27
38
|
"expo": {
|
|
28
39
|
"plugins": [
|
|
40
|
+
"rns-nativecall",
|
|
29
41
|
[
|
|
30
42
|
"expo-build-properties",
|
|
31
43
|
{
|
|
@@ -33,19 +45,35 @@ Add the plugin to your app.json or app.config.js:
|
|
|
33
45
|
"enableProguardInReleaseBuilds": true,
|
|
34
46
|
"extraProguardRules": "-keep class com.rnsnativecall.** { *; }\n-keep class com.facebook.react.HeadlessJsTaskService { *; }"
|
|
35
47
|
}
|
|
36
|
-
}
|
|
37
|
-
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
"expo-notifications",
|
|
52
|
+
{
|
|
53
|
+
"icon": "./assets/notification_icon.png",
|
|
54
|
+
"color": "#218aff",
|
|
55
|
+
"iosDisplayInForeground": true,
|
|
56
|
+
"androidPriority": "high",
|
|
57
|
+
"androidVibrate": true,
|
|
58
|
+
"androidSound": true,
|
|
59
|
+
"androidImportance": "high",
|
|
60
|
+
"androidLightColor": "#218aff",
|
|
61
|
+
"androidVisibility": "public"
|
|
62
|
+
}
|
|
38
63
|
]
|
|
39
64
|
]
|
|
40
65
|
}
|
|
41
66
|
}
|
|
42
|
-
|
|
43
67
|
```
|
|
68
|
+
|
|
44
69
|
---
|
|
45
|
-
### ๐ Usage
|
|
46
70
|
|
|
47
|
-
|
|
48
|
-
|
|
71
|
+
## ๐ Usage
|
|
72
|
+
|
|
73
|
+
### 1๏ธโฃ Register Headless Task (index.js)
|
|
74
|
+
|
|
75
|
+
This enables background handling, busy-state signaling, and cold-start execution.
|
|
76
|
+
|
|
49
77
|
```javascript
|
|
50
78
|
import { AppRegistry } from 'react-native';
|
|
51
79
|
import App from './App';
|
|
@@ -53,50 +81,39 @@ import { CallHandler } from 'rns-nativecall';
|
|
|
53
81
|
|
|
54
82
|
CallHandler.registerHeadlessTask(async (data, eventType) => {
|
|
55
83
|
if (eventType === 'BUSY') {
|
|
56
|
-
|
|
57
|
-
console.log("System Busy for UUID:", data.callUuid);
|
|
84
|
+
console.log("User already in call:", data.callUuid);
|
|
58
85
|
return;
|
|
59
86
|
}
|
|
60
87
|
|
|
61
88
|
if (eventType === 'INCOMING_CALL') {
|
|
62
|
-
|
|
63
|
-
// Trigger your custom UI or logic here.
|
|
89
|
+
console.log("Incoming call payload:", data);
|
|
64
90
|
}
|
|
65
91
|
});
|
|
66
92
|
|
|
67
93
|
AppRegistry.registerComponent('main', () => App);
|
|
68
94
|
```
|
|
69
|
-
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## ๐ง Foreground Event Handling (index.js)
|
|
70
99
|
|
|
71
100
|
```javascript
|
|
72
|
-
// Index.js Setup Foreground Listeners
|
|
73
101
|
CallHandler.subscribe(
|
|
74
|
-
|
|
75
102
|
async (data) => {
|
|
76
|
-
|
|
77
|
-
console.log("APP IS OPEN", data)
|
|
78
|
-
// navigate here
|
|
79
|
-
} catch (error) {
|
|
80
|
-
console.log("pending_call_uuid", error)
|
|
81
|
-
}
|
|
103
|
+
console.log("CALL ACCEPTED", data);
|
|
82
104
|
},
|
|
83
|
-
|
|
84
105
|
async (data) => {
|
|
85
|
-
|
|
86
|
-
console.log("CALL DECLINE", data)
|
|
87
|
-
// update the caller here call decline
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.log("Onreject/ cancel call error", error)
|
|
90
|
-
}
|
|
106
|
+
console.log("CALL REJECTED", data);
|
|
91
107
|
},
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
(data) => {
|
|
109
|
+
console.log("CALL FAILED", data);
|
|
110
|
+
}
|
|
94
111
|
);
|
|
112
|
+
```
|
|
95
113
|
|
|
114
|
+
---
|
|
96
115
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
## Handling Events (App.js)
|
|
116
|
+
## ๐ฌ App-Level Integration (App.js)
|
|
100
117
|
|
|
101
118
|
```javascript
|
|
102
119
|
import React, { useEffect } from 'react';
|
|
@@ -107,18 +124,15 @@ export default function App() {
|
|
|
107
124
|
const unsubscribe = CallHandler.subscribe(
|
|
108
125
|
(data) => {
|
|
109
126
|
console.log("Call Accepted:", data.callUuid);
|
|
110
|
-
// Navigate to your call screen
|
|
111
127
|
},
|
|
112
128
|
(data) => {
|
|
113
129
|
console.log("Call Rejected:", data.callUuid);
|
|
114
|
-
// Send 'Hangup' signal to your server
|
|
115
130
|
}
|
|
116
131
|
);
|
|
117
132
|
|
|
118
133
|
return () => unsubscribe();
|
|
119
134
|
}, []);
|
|
120
135
|
|
|
121
|
-
// To manually trigger the UI (e.g., from an FCM data message)
|
|
122
136
|
const showCall = () => {
|
|
123
137
|
CallHandler.displayCall("unique-uuid", "Caller Name", "video");
|
|
124
138
|
};
|
|
@@ -126,54 +140,66 @@ export default function App() {
|
|
|
126
140
|
return <YourUI />;
|
|
127
141
|
}
|
|
128
142
|
```
|
|
143
|
+
|
|
129
144
|
---
|
|
130
|
-
## ๐ rns-nativecall API Reference
|
|
131
145
|
|
|
146
|
+
## ๐ API Reference
|
|
132
147
|
|
|
133
148
|
### Core Methods
|
|
149
|
+
|
|
134
150
|
| Method | Platform | Description |
|
|
135
|
-
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
|
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
|
|
|
142
|
-
|
|
143
|
-
|
|
151
|
+
|------|---------|-------------|
|
|
152
|
+
| `registerHeadlessTask(cb)` | All | Registers background task (`INCOMING_CALL`, `BUSY`, `ABORTED_CALL`) |
|
|
153
|
+
| `displayCall(uuid, name, type)` | All | Shows native incoming call UI |
|
|
154
|
+
| `destroyNativeCallUI(uuid)` | All | Ends native UI / CallKit session |
|
|
155
|
+
| `subscribe(onAccept, onReject, onFail)` | All | Listen to call actions |
|
|
156
|
+
| `showMissedCall(uuid, name, type)` | Android | Persistent missed call notification |
|
|
157
|
+
| `showOnGoingCall(uuid, name, type)` | Android | Persistent ongoing call notification |
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
### Data & State
|
|
162
|
+
|
|
144
163
|
| Method | Platform | Description |
|
|
145
|
-
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
164
|
+
|------|---------|-------------|
|
|
165
|
+
| `getInitialCallData()` | All | Retrieve payload from cold start |
|
|
166
|
+
| `checkCallValidity(uuid)` | All | Prevent ghost calls |
|
|
167
|
+
| `checkCallStatus(uuid)` | All | Sync UI with native state |
|
|
168
|
+
|
|
169
|
+
---
|
|
149
170
|
|
|
150
171
|
### Android Permissions
|
|
151
|
-
|
|
152
|
-
|
|
|
153
|
-
|
|
154
|
-
|
|
|
155
|
-
|
|
|
156
|
-
|
|
|
172
|
+
|
|
173
|
+
| Method | Description |
|
|
174
|
+
|------|-------------|
|
|
175
|
+
| `checkOverlayPermission()` | Check lockscreen overlay permission |
|
|
176
|
+
| `requestOverlayPermission()` | Open overlay settings |
|
|
177
|
+
| `checkFullScreenPermission()` | Android 14+ full screen intent |
|
|
178
|
+
| `requestFullScreenSettings()` | Android 14+ permission screen |
|
|
157
179
|
|
|
158
180
|
---
|
|
159
181
|
|
|
160
|
-
|
|
182
|
+
## ๐ง Implementation Notes
|
|
161
183
|
|
|
162
|
-
|
|
163
|
-
|
|
184
|
+
### Android Overlay
|
|
185
|
+
Overlay permission is required to display calls on the lockscreen.
|
|
186
|
+
Request during onboarding or before first call.
|
|
164
187
|
|
|
165
|
-
|
|
166
|
-
|
|
188
|
+
### iOS CallKit
|
|
189
|
+
Uses system CallKit UI. Works automatically in background and lockscreen.
|
|
190
|
+
|
|
191
|
+
### Single Call Gate
|
|
192
|
+
If a call is active, all subsequent calls emit `BUSY` via headless task.
|
|
167
193
|
|
|
168
|
-
3. Single Call Gate:
|
|
169
|
-
The library automatically prevents multiple overlapping native UIs. If a call is already active, subsequent calls will trigger the 'BUSY' event in your Headless Task.
|
|
170
194
|
---
|
|
171
195
|
|
|
172
|
-
##
|
|
173
|
-
|
|
196
|
+
## ๐งช Full Example
|
|
197
|
+
|
|
198
|
+
```js
|
|
174
199
|
import React, { useEffect, useState } from 'react';
|
|
175
200
|
import { StyleSheet, Text, View, TouchableOpacity, Alert } from 'react-native';
|
|
176
201
|
import { CallHandler } from 'rns-nativecall';
|
|
202
|
+
import uuid from 'react-native-uuid';
|
|
177
203
|
|
|
178
204
|
export default function App() {
|
|
179
205
|
const [activeCall, setActiveCall] = useState(null);
|
|
@@ -220,7 +246,7 @@ export default function App() {
|
|
|
220
246
|
|
|
221
247
|
// Trigger the native UI
|
|
222
248
|
CallHandler.displayCall(
|
|
223
|
-
|
|
249
|
+
uuid.v4(),
|
|
224
250
|
"John Doe",
|
|
225
251
|
"video"
|
|
226
252
|
);
|
|
@@ -262,5 +288,13 @@ const styles = StyleSheet.create({
|
|
|
262
288
|
btnText: { color: 'white', fontWeight: 'bold' }
|
|
263
289
|
});
|
|
264
290
|
```
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
265
294
|
## ๐ก License
|
|
295
|
+
|
|
296
|
+
MIT License
|
|
297
|
+
|
|
266
298
|
---
|
|
299
|
+
|
|
300
|
+
Built for **production VoIP apps**, not demos.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rns-nativecall",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "High-performance React Native module for handling native VoIP call UI on Android and iOS.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"url": "git+https://github.com/raiidr/rns-nativecall.git"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
|
-
"p": "npm publish --access public"
|
|
23
|
+
"p": "npm publish --access public",
|
|
24
|
+
"i": "npm publish --access public"
|
|
24
25
|
},
|
|
25
26
|
"keywords": [
|
|
26
27
|
"react-native",
|
|
@@ -47,6 +48,8 @@
|
|
|
47
48
|
"react-native": ">=0.60.0"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
|
-
"@expo/config-plugins": "^9.0.0"
|
|
51
|
+
"@expo/config-plugins": "^9.0.0",
|
|
52
|
+
"react-native-uuid": "^2.0.3",
|
|
53
|
+
"expo-build-properties": "~0.14.8"
|
|
51
54
|
}
|
|
52
55
|
}
|
package/withNativeCallVoip.js
CHANGED
|
@@ -107,6 +107,7 @@ function withAndroidConfig(config) {
|
|
|
107
107
|
'android.permission.POST_NOTIFICATIONS',
|
|
108
108
|
'android.permission.WAKE_LOCK',
|
|
109
109
|
'android.permission.DISABLE_KEYGUARD',
|
|
110
|
+
'android.permission.MANAGE_OWN_CALLS',
|
|
110
111
|
];
|
|
111
112
|
|
|
112
113
|
manifest.manifest['uses-permission'] = manifest.manifest['uses-permission'] || [];
|