rns-nativecall 1.1.8 → 1.2.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/README.md
CHANGED
|
@@ -132,16 +132,18 @@ export default function App() {
|
|
|
132
132
|
|
|
133
133
|
| Method | Platform | Description |
|
|
134
134
|
| :--- | :--- | :--- |
|
|
135
|
-
| **registerHeadlessTask(callback)** | Android | Registers background logic. `eventType` is `INCOMING_CALL` or `
|
|
136
|
-
| **checkOverlayPermission()** | Android | Returns true if the app can draw over other apps (Required for
|
|
135
|
+
| **registerHeadlessTask(callback)** | Android | Registers background logic. `eventType` is `INCOMING_CALL`, `BUSY`, or `ABORTED_CALL`. |
|
|
136
|
+
| **checkOverlayPermission()** | Android | Returns true if the app can draw over other apps (Required for overlay UI). |
|
|
137
137
|
| **requestOverlayPermission()** | Android | Opens System Settings to let the user enable "Draw over other apps". |
|
|
138
|
-
| **
|
|
139
|
-
| **
|
|
140
|
-
| **
|
|
141
|
-
| **
|
|
142
|
-
| **
|
|
143
|
-
| **
|
|
144
|
-
|
|
138
|
+
| **checkFullScreenPermission()** | Android | [Android 14+] Checks if the app is allowed to show full-screen intents on the lockscreen. |
|
|
139
|
+
| **requestFullScreenSettings()** | Android | [Android 14+] Opens System Settings to enable the Full Screen Intent permission. |
|
|
140
|
+
| **displayCall(uuid, name, type)** | Android | Shows the native full-screen call UI and starts the ringtone. |
|
|
141
|
+
| **checkCallValidity(uuid)** | Android | Returns `{isValid, isCanceled}` based on persistent state and CANCEL signals. |
|
|
142
|
+
| **checkCallStatus(uuid)** | Android | Returns `{isCanceled, isActive, shouldDisplay}` for UI synchronization. |
|
|
143
|
+
| **reportRemoteEnded(uuid, reason)** | Android | Tells the native side the caller hung up so the UI can dismiss automatically. |
|
|
144
|
+
| **destroyNativeCallUI(uuid)** | Android | Forcefully dismisses the native interface, stops audio, and clears the current call state. |
|
|
145
|
+
| **getInitialCallData()** | Android | Returns the call payload if the app was cold-started by a notification interaction. |
|
|
146
|
+
| **subscribe(onAccept, onReject, onFailed)** | Android | Listens for native Answer/Decline button presses and system errors. |
|
|
145
147
|
---
|
|
146
148
|
|
|
147
149
|
# Implementation Notes
|
|
@@ -61,7 +61,6 @@ class CallModule(
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// Inside your CallModule class
|
|
65
64
|
@ReactMethod
|
|
66
65
|
fun checkOverlayPermission(promise: Promise) {
|
|
67
66
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
@@ -71,6 +70,16 @@ class CallModule(
|
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
|
|
73
|
+
@ReactMethod
|
|
74
|
+
fun reportRemoteEnded(
|
|
75
|
+
uuid: String,
|
|
76
|
+
reason: String,
|
|
77
|
+
promise: Promise,
|
|
78
|
+
) {
|
|
79
|
+
NativeCallManager.dismissIncomingCall(reactApplicationContext, uuid)
|
|
80
|
+
promise.resolve(true)
|
|
81
|
+
}
|
|
82
|
+
|
|
74
83
|
@ReactMethod
|
|
75
84
|
fun requestOverlayPermission() {
|
|
76
85
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
@@ -86,10 +95,39 @@ class CallModule(
|
|
|
86
95
|
}
|
|
87
96
|
}
|
|
88
97
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
@ReactMethod
|
|
99
|
+
fun checkFullScreenIntentPermission(promise: Promise) {
|
|
100
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
101
|
+
val notificationManager = reactApplicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
102
|
+
promise.resolve(notificationManager.canUseFullScreenIntent())
|
|
103
|
+
} else {
|
|
104
|
+
// Automatically true for Android 13 and below
|
|
105
|
+
promise.resolve(true)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@ReactMethod
|
|
110
|
+
fun requestFullScreenSettings() {
|
|
111
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
112
|
+
try {
|
|
113
|
+
val intent =
|
|
114
|
+
Intent(Settings.ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT).apply {
|
|
115
|
+
data = Uri.fromParts("package", reactApplicationContext.packageName, null)
|
|
116
|
+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
117
|
+
}
|
|
118
|
+
reactApplicationContext.startActivity(intent)
|
|
119
|
+
} catch (e: Exception) {
|
|
120
|
+
// Fallback for some OEM skins that might not support the direct intent
|
|
121
|
+
val intent =
|
|
122
|
+
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
|
123
|
+
data = Uri.fromParts("package", reactApplicationContext.packageName, null)
|
|
124
|
+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
125
|
+
}
|
|
126
|
+
reactApplicationContext.startActivity(intent)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
93
131
|
@ReactMethod
|
|
94
132
|
fun checkCallValidity(
|
|
95
133
|
uuid: String,
|
|
@@ -107,22 +145,6 @@ class CallModule(
|
|
|
107
145
|
promise.resolve(map)
|
|
108
146
|
}
|
|
109
147
|
|
|
110
|
-
@ReactMethod
|
|
111
|
-
fun stopForegroundService(promise: Promise) {
|
|
112
|
-
try {
|
|
113
|
-
// Using the current react context to stop the service
|
|
114
|
-
val intent = Intent(reactApplicationContext, CallForegroundService::class.java)
|
|
115
|
-
reactApplicationContext.stopService(intent)
|
|
116
|
-
promise.resolve(true)
|
|
117
|
-
} catch (e: Exception) {
|
|
118
|
-
promise.reject("SERVICE_STOP_ERROR", e.message)
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* General Status Check:
|
|
124
|
-
* Useful for checking if the UI is still relevant.
|
|
125
|
-
*/
|
|
126
148
|
@ReactMethod
|
|
127
149
|
fun checkCallStatus(
|
|
128
150
|
uuid: String,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/////Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallPackage.kt
|
|
2
1
|
package com.rnsnativecall
|
|
3
2
|
|
|
4
3
|
import com.facebook.react.ReactPackage
|
|
@@ -7,11 +6,7 @@ import com.facebook.react.bridge.ReactApplicationContext
|
|
|
7
6
|
import com.facebook.react.uimanager.ViewManager
|
|
8
7
|
|
|
9
8
|
class CallPackage : ReactPackage {
|
|
10
|
-
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule>
|
|
11
|
-
return listOf(CallModule(reactContext))
|
|
12
|
-
}
|
|
9
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> = listOf(CallModule(reactContext))
|
|
13
10
|
|
|
14
|
-
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>>
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
}
|
|
11
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> = emptyList()
|
|
12
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -48,7 +48,6 @@ export interface CallHandlerType {
|
|
|
48
48
|
/**
|
|
49
49
|
* Registers the background "Headless" task.
|
|
50
50
|
* This is the bridge between a Native push notification and your React Native UI.
|
|
51
|
-
* * @param callback Async function receiving call data and the event type.
|
|
52
51
|
*/
|
|
53
52
|
registerHeadlessTask(
|
|
54
53
|
callback: (data: CallData, eventType: CallEventType) => Promise<void>
|
|
@@ -56,58 +55,55 @@ export interface CallHandlerType {
|
|
|
56
55
|
|
|
57
56
|
/**
|
|
58
57
|
* Displays the full-screen Native Incoming Call UI.
|
|
59
|
-
* Usually called inside registerHeadlessTask after validating the call.
|
|
60
|
-
* * @param uuid The unique call ID.
|
|
61
|
-
* @param name Name to display on the call screen.
|
|
62
|
-
* @param callType Defaults to 'audio'.
|
|
63
|
-
* @returns Promise resolving to true if the UI was successfully launched.
|
|
64
58
|
*/
|
|
65
59
|
displayCall(
|
|
66
60
|
uuid: string,
|
|
67
61
|
name: string,
|
|
68
|
-
callType
|
|
62
|
+
callType?: 'audio' | 'video',
|
|
69
63
|
): Promise<boolean>;
|
|
70
64
|
|
|
71
65
|
/** * Checks if a call is still valid and has not been canceled.
|
|
72
|
-
* Useful for Splash screen "Interceptors" to prevent ghost calls.
|
|
73
66
|
*/
|
|
74
67
|
checkCallValidity(uuid: string): Promise<ValidityStatus>;
|
|
75
68
|
|
|
76
69
|
/** * Detailed check of a call's status.
|
|
77
|
-
* Useful for determining if the UI should remain visible.
|
|
78
70
|
*/
|
|
79
71
|
checkCallStatus(uuid: string): Promise<CallStatus>;
|
|
80
72
|
|
|
81
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Checks if the app has permission to draw over other apps (Overlay).
|
|
75
|
+
*/
|
|
76
|
+
checkOverlayPermission(): Promise<boolean>;
|
|
82
77
|
|
|
83
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Opens system settings to request the "Draw over other apps" (Overlay) permission.
|
|
80
|
+
* Note: Returns a promise that resolves to false if module is missing.
|
|
81
|
+
*/
|
|
82
|
+
requestOverlayPermission(): Promise<boolean | void>;
|
|
84
83
|
|
|
85
|
-
|
|
84
|
+
/**
|
|
85
|
+
* [Android 14+] Opens the specific system settings page for Full Screen Intent.
|
|
86
|
+
*/
|
|
87
|
+
requestFullScreenSettings(): Promise<boolean | void>;
|
|
86
88
|
|
|
87
89
|
/**
|
|
88
|
-
*
|
|
89
|
-
* Use this when the call is hung up or timed out.
|
|
90
|
+
* Reports to the native side that the remote party has terminated the call.
|
|
90
91
|
*/
|
|
91
|
-
|
|
92
|
+
reportRemoteEnded(uuid: string, reason?: string): Promise<void>;
|
|
92
93
|
|
|
93
94
|
/**
|
|
94
|
-
*
|
|
95
|
-
* MUST be called after displayCall() or when a BUSY signal is handled to
|
|
96
|
-
* remove the persistent system notification.
|
|
95
|
+
* Forcefully dismisses the native call UI, stops the ringtone, and clears state.
|
|
97
96
|
*/
|
|
98
|
-
|
|
97
|
+
destroyNativeCallUI(uuid: string): void;
|
|
99
98
|
|
|
100
99
|
/**
|
|
101
|
-
* Retrieves call data if the app was launched directly from an interaction
|
|
102
|
-
*
|
|
100
|
+
* Retrieves call data if the app was launched directly from an interaction.
|
|
101
|
+
* Returns the 'default' payload or the raw data object.
|
|
103
102
|
*/
|
|
104
103
|
getInitialCallData(): Promise<any | null>;
|
|
105
104
|
|
|
106
105
|
/**
|
|
107
106
|
* Subscribes to user interactions on the Native Call UI.
|
|
108
|
-
* * @param onAccept Callback when user presses the Answer button.
|
|
109
|
-
* @param onReject Callback when user presses the Decline button.
|
|
110
|
-
* @param onFailed Callback for system errors (optional).
|
|
111
107
|
* @returns A cleanup function to unsubscribe.
|
|
112
108
|
*/
|
|
113
109
|
subscribe(
|
|
@@ -120,5 +116,5 @@ export interface CallHandlerType {
|
|
|
120
116
|
/**
|
|
121
117
|
* Main handler for Native VoIP Call interactions.
|
|
122
118
|
*/
|
|
123
|
-
|
|
119
|
+
export const CallHandler: CallHandlerType;
|
|
124
120
|
export default CallHandler;
|
package/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
const { CallModule } = NativeModules;
|
|
8
8
|
const callEventEmitter = CallModule ? new NativeEventEmitter(CallModule) : null;
|
|
9
9
|
|
|
10
|
+
|
|
10
11
|
export const CallHandler = {
|
|
11
12
|
registerHeadlessTask: (onAction) => {
|
|
12
13
|
AppRegistry.registerHeadlessTask('ColdStartCallTask', () => async (data) => {
|
|
@@ -57,6 +58,11 @@ export const CallHandler = {
|
|
|
57
58
|
return await CallModule.requestOverlayPermission();
|
|
58
59
|
},
|
|
59
60
|
|
|
61
|
+
requestFullScreenSettings: async () => {
|
|
62
|
+
if (!CallModule?.requestFullScreenSettings) return false;
|
|
63
|
+
return await CallModule.requestFullScreenSettings();
|
|
64
|
+
},
|
|
65
|
+
|
|
60
66
|
checkOverlayPermission: async () => {
|
|
61
67
|
if (!CallModule?.checkOverlayPermission) return false;
|
|
62
68
|
return await CallModule.checkOverlayPermission();
|
|
@@ -67,21 +73,19 @@ export const CallHandler = {
|
|
|
67
73
|
return await CallModule.displayIncomingCall(uuid.toLowerCase().trim(), name, callType);
|
|
68
74
|
},
|
|
69
75
|
|
|
70
|
-
stopForegroundService: async () => {
|
|
71
|
-
if (CallModule?.stopForegroundService) {
|
|
72
|
-
await CallModule.stopForegroundService();
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
|
|
76
76
|
destroyNativeCallUI: (uuid) => {
|
|
77
77
|
if (CallModule?.endNativeCall) {
|
|
78
78
|
CallModule.endNativeCall(uuid.toLowerCase().trim());
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
81
|
|
|
82
|
+
|
|
82
83
|
getInitialCallData: async () => {
|
|
83
84
|
if (!CallModule?.getInitialCallData) return null;
|
|
84
|
-
|
|
85
|
+
const data = await CallModule.getInitialCallData();
|
|
86
|
+
|
|
87
|
+
// Return the 'default' call data if it exists, otherwise the whole object
|
|
88
|
+
return data?.default || data;
|
|
85
89
|
},
|
|
86
90
|
|
|
87
91
|
subscribe: (onAccept, onReject, onFailed) => {
|