rns-nativecall 0.9.7 → 0.9.9
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 +125 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,8 +49,8 @@ CallHandler.registerHeadlessTask(async (data, eventType) => {
|
|
|
49
49
|
|
|
50
50
|
AppRegistry.registerComponent('main', () => App);
|
|
51
51
|
```
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
## Handling Events (Index.js)
|
|
53
|
+
|
|
54
54
|
```javascript
|
|
55
55
|
// Index.js Setup Foreground Listeners
|
|
56
56
|
CallHandler.subscribe(
|
|
@@ -79,8 +79,7 @@ CallHandler.subscribe(
|
|
|
79
79
|
|
|
80
80
|
````
|
|
81
81
|
|
|
82
|
-
## App.js
|
|
83
|
-
|
|
82
|
+
## Handling Events (App.js)
|
|
84
83
|
|
|
85
84
|
```javascript
|
|
86
85
|
import React, { useEffect } from 'react';
|
|
@@ -112,14 +111,129 @@ export default function App() {
|
|
|
112
111
|
```
|
|
113
112
|
---
|
|
114
113
|
### 📖 API Reference
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
| **
|
|
120
|
-
| **
|
|
121
|
-
| **
|
|
114
|
+
# rns-nativecall API Reference
|
|
115
|
+
|
|
116
|
+
| Method | Platform | Description |
|
|
117
|
+
| :--- | :--- | :--- |
|
|
118
|
+
| **registerHeadlessTask(callback)** | Android | Registers background logic. `eventType` is `INCOMING_CALL` or `BUSY`. |
|
|
119
|
+
| **checkOverlayPermission()** | Android | Returns true if the app can draw over other apps (Required for Android Lockscreen). |
|
|
120
|
+
| **requestOverlayPermission()** | Android | Opens System Settings to let the user enable "Draw over other apps". |
|
|
121
|
+
| **displayCall(uuid, name, type)** | All | Shows the native call UI (Standard Notification on Android / CallKit on iOS). |
|
|
122
|
+
| **checkCallValidity(uuid)** | All | Returns boolean values for `isValid` and `isCanceled`. |
|
|
123
|
+
| **stopForegroundService()** | Android | Stops the ongoing service and clears the persistent notification/pill. |
|
|
124
|
+
| **destroyNativeCallUI(uuid)** | All | Dismisses the native call interface and stops the ringtone. |
|
|
125
|
+
| **getInitialCallData()** | All | Returns call data if the app was launched by clicking `Answer` from a killed state. |
|
|
126
|
+
| **subscribe(onAccept, onReject)** | All | Listens for native button presses (Answer/End). |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
# Implementation Notes
|
|
131
|
+
|
|
132
|
+
1. Android Persistence:
|
|
133
|
+
Because this library uses a Foreground Service on Android, the notification will persist and show a "Call Pill" in the status bar. To remove this after the call ends or connects, you MUST call 'CallHandler.stopForegroundService()'.
|
|
134
|
+
|
|
135
|
+
2. Android Overlay:
|
|
136
|
+
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.
|
|
137
|
+
|
|
138
|
+
3. iOS CallKit:
|
|
139
|
+
On iOS, 'displayCall' uses the native system CallKit UI. This works automatically in the background and on the lockscreen without extra overlay permissions.
|
|
140
|
+
|
|
141
|
+
4. Single Call Gate:
|
|
142
|
+
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.
|
|
122
143
|
---
|
|
123
144
|
|
|
145
|
+
## FULL Example Use Case
|
|
146
|
+
```javascript
|
|
147
|
+
import React, { useEffect, useState } from 'react';
|
|
148
|
+
import { StyleSheet, Text, View, TouchableOpacity, Alert } from 'react-native';
|
|
149
|
+
import { CallHandler } from 'rns-nativecall';
|
|
150
|
+
|
|
151
|
+
export default function App() {
|
|
152
|
+
const [activeCall, setActiveCall] = useState(null);
|
|
153
|
+
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
// 1. Handle app launched from a notification "Answer" click
|
|
156
|
+
CallHandler.getInitialCallData().then((data) => {
|
|
157
|
+
if (data && data.default) {
|
|
158
|
+
console.log("App launched from call:", data.default);
|
|
159
|
+
setActiveCall(data.default);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// 2. Subscribe to foreground events
|
|
164
|
+
const unsubscribe = CallHandler.subscribe(
|
|
165
|
+
(data) => {
|
|
166
|
+
console.log("Call Accepted:", data.callUuid);
|
|
167
|
+
setActiveCall(data);
|
|
168
|
+
// Logic: Open your Video/Audio Call UI here
|
|
169
|
+
},
|
|
170
|
+
(data) => {
|
|
171
|
+
console.log("Call Rejected/Ended:", data.callUuid);
|
|
172
|
+
setActiveCall(null);
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
return () => unsubscribe();
|
|
177
|
+
}, []);
|
|
178
|
+
|
|
179
|
+
const startTestCall = async () => {
|
|
180
|
+
// Android Only: Check for overlay permission to show UI over lockscreen
|
|
181
|
+
const hasPermission = await CallHandler.checkOverlayPermission();
|
|
182
|
+
if (!hasPermission) {
|
|
183
|
+
Alert.alert(
|
|
184
|
+
"Permission Required",
|
|
185
|
+
"Please enable 'Draw over other apps' to see calls while the phone is locked.",
|
|
186
|
+
[
|
|
187
|
+
{ text: "Cancel" },
|
|
188
|
+
{ text: "Settings", onPress: () => CallHandler.requestOverlayPermission() }
|
|
189
|
+
]
|
|
190
|
+
);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Trigger the native UI
|
|
195
|
+
CallHandler.displayCall(
|
|
196
|
+
"test-uuid-" + Date.now(),
|
|
197
|
+
"John Doe",
|
|
198
|
+
"video"
|
|
199
|
+
);
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const endCallManually = () => {
|
|
203
|
+
if (activeCall) {
|
|
204
|
+
CallHandler.stopForegroundService();
|
|
205
|
+
setActiveCall(null);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<View style={styles.container}>
|
|
211
|
+
<Text style={styles.title}>RNS Native Call Pro</Text>
|
|
212
|
+
|
|
213
|
+
{activeCall ? (
|
|
214
|
+
<View style={styles.callBox}>
|
|
215
|
+
<Text>Active Call with: {activeCall.name}</Text>
|
|
216
|
+
<TouchableOpacity style={styles.btnEnd} onPress={endCallManually}>
|
|
217
|
+
<Text style={styles.btnText}>End Call</Text>
|
|
218
|
+
</TouchableOpacity>
|
|
219
|
+
</View>
|
|
220
|
+
) : (
|
|
221
|
+
<TouchableOpacity style={styles.btnStart} onPress={startTestCall}>
|
|
222
|
+
<Text style={styles.btnText}>Simulate Incoming Call</Text>
|
|
223
|
+
</TouchableOpacity>
|
|
224
|
+
)}
|
|
225
|
+
</View>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const styles = StyleSheet.create({
|
|
230
|
+
container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF' },
|
|
231
|
+
title: { fontSize: 20, fontWeight: 'bold', marginBottom: 20 },
|
|
232
|
+
callBox: { padding: 20, backgroundColor: '#e1f5fe', borderRadius: 10, alignItems: 'center' },
|
|
233
|
+
btnStart: { backgroundColor: '#4CAF50', padding: 15, borderRadius: 5 },
|
|
234
|
+
btnEnd: { backgroundColor: '#F44336', padding: 15, borderRadius: 5, marginTop: 10 },
|
|
235
|
+
btnText: { color: 'white', fontWeight: 'bold' }
|
|
236
|
+
});
|
|
237
|
+
```
|
|
124
238
|
## 🛡 License
|
|
125
239
|
---
|