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 CHANGED
@@ -1,31 +1,43 @@
1
1
  # rns-nativecall
2
2
 
3
- A professional VoIP incoming call handler for React Native. Features a "Single Call Gate" on Android to manage busy states and full CallKit integration for iOS.
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
- - **Expo Support**: Built-in config plugin handles all native setup.
7
- - **Single Call Gate**: Automatically detects if the user is in a call and flags secondary calls as "BUSY".
8
- - **Headless Mode**: Works even when the app is killed or the screen is locked.
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
- Add the plugin to your app.json or app.config.js:
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
- "rns-nativecall"
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
- 1. Initialize Headless Task (index.js)
48
- Register the task at the very top of your entry file. This handles background calls and "Busy" signals for secondary callers.
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
- // User is already on a call. Notify the second caller via WebSocket/API.
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
- // App is waking up for a new call.
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
- ## Handling Events (Index.js)
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
- try {
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
- try {
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
- (data) => { console.log("failded", data) }
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
- | **registerHeadlessTask(callback)** | All | Registers the background task. `eventType` is 'INCOMING_CALL', 'BUSY', or 'ABORTED_CALL'. |
137
- | **displayCall(uuid, name, type)** | All | Launches full-screen Activity (Android) or reports to CallKit (iOS). |
138
- | **destroyNativeCallUI(uuid)** | All | Stops ringtone/Activity (Android) or ends CallKit session (iOS). |
139
- | **subscribe(onAccept, onReject, onFailed)** | All | Listens for Answer/Decline actions and system-level bridge errors. |
140
- | **showMissedCall(uuid, name, type)** | Android | Posts a persistent notification in the device tray for missed calls. |
141
- | **showOnGoingCall(uuid, name, type)** | Android | Show a persistent notification in the device tray for on going calls. |
142
-
143
- ### Data & State Management
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
- | **getInitialCallData()** | All | Retrieves the call payload if the app was cold-started via a notification. |
147
- | **checkCallValidity(uuid)** | All | Returns `{isValid, isCanceled}` to prevent ghost or aborted calls. |
148
- | **checkCallStatus(uuid)** | All | Returns `{isCanceled, isActive, shouldDisplay}` for UI syncing. |
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
- | Method | Platform | Description |
152
- | :--- | :--- | :--- |
153
- | **checkOverlayPermission()** | Android | Returns `true` if app can draw over other apps (Heads-up UI). |
154
- | **checkFullScreenPermission()** | Android | (Android 14+) Checks if app can trigger full-screen intents. |
155
- | **requestOverlayPermission()** | Android | Navigates user to "Draw over other apps" system settings. |
156
- | **requestFullScreenSettings()** | Android | (Android 14+) Navigates user to "Full Screen Intent" settings. |
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
- # Implementation Notes
182
+ ## ๐Ÿง  Implementation Notes
161
183
 
162
- 1. Android Overlay:
163
- For your React Native call screen to show up when the phone is locked, the user must grant the "Overlay Permission". Use 'checkOverlayPermission()' and 'requestOverlayPermission()' during your app's onboarding or call initiation.
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
- 2. iOS CallKit:
166
- On iOS, 'displayCall' uses the native system CallKit UI. This works automatically in the background and on the lockscreen without extra overlay permissions.
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
- ## FULL Example Use Case
173
- ```javascript
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
- "test-uuid-" + Date.now(),
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.0",
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
  }
@@ -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'] || [];