rns-nativecall 0.0.3 → 0.0.5

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.
Files changed (3) hide show
  1. package/index.d.ts +17 -10
  2. package/index.js +30 -48
  3. package/package.json +12 -6
package/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  ///Users/bush/Desktop/Apps/Raiidr/package/index.d.ts
2
+
2
3
  export interface CallData {
3
4
  callUUID: string;
4
5
  }
@@ -7,14 +8,20 @@ export type CallAcceptedCallback = (data: CallData) => void;
7
8
  export type CallRejectedCallback = (data: CallData) => void;
8
9
  export type CallFailedCallback = (data: CallData) => void;
9
10
 
11
+ /**
12
+ * Manually request/check Android permissions for Telecom.
13
+ * @returns Promise resolving to true if granted
14
+ */
15
+ export function ensureAndroidPermissions(): Promise<boolean>;
16
+
10
17
  export interface CallHandlerType {
11
18
  /**
12
- * Display an incoming call UI.
19
+ * Display an incoming call UI using ConnectionService (Android) or CallKit (iOS).
13
20
  * @param uuid Unique call identifier
14
- * @param number Caller number
21
+ * @param number Caller number (or URI)
15
22
  * @param name Caller display name
16
- * @param hasVideo True if video call
17
- * @param shouldRing True to play native ringtone
23
+ * @param hasVideo True if video call (default: false)
24
+ * @param shouldRing True to play native ringtone (default: true)
18
25
  * @returns Promise resolving to true if successfully displayed
19
26
  */
20
27
  displayCall(
@@ -26,16 +33,16 @@ export interface CallHandlerType {
26
33
  ): Promise<boolean>;
27
34
 
28
35
  /**
29
- * Dismiss native call UI
36
+ * Dismiss the native call UI (e.g., if the caller hangs up before the user answers).
30
37
  * @param uuid Call identifier
31
38
  */
32
39
  destroyNativeCallUI(uuid: string): void;
33
40
 
34
41
  /**
35
- * Subscribe to call events
36
- * @param onAccept Callback for accepted calls
37
- * @param onReject Callback for rejected calls
38
- * @param onFailed Optional callback for failed calls
42
+ * Subscribe to call events from the native side.
43
+ * @param onAccept Callback when user presses Answer
44
+ * @param onReject Callback when user presses Decline
45
+ * @param onFailed Optional callback for system-level failures
39
46
  * @returns Function to unsubscribe all listeners
40
47
  */
41
48
  subscribe(
@@ -47,4 +54,4 @@ export interface CallHandlerType {
47
54
 
48
55
  declare const CallHandler: CallHandlerType;
49
56
 
50
- export default CallHandler;
57
+ export default CallHandler;
package/index.js CHANGED
@@ -9,6 +9,15 @@ import {
9
9
  } from 'react-native';
10
10
 
11
11
  const { CallModule } = NativeModules;
12
+
13
+ // Safety check for the Native Module
14
+ if (!CallModule && __DEV__) {
15
+ console.warn(
16
+ "rns-nativecall: NativeModule.CallModule is undefined. " +
17
+ "Make sure you have rebuilt your native project (npx expo run:android / ios)."
18
+ );
19
+ }
20
+
12
21
  const callEventEmitter = CallModule ? new NativeEventEmitter(CallModule) : null;
13
22
 
14
23
  const REQUIRED_PERMISSIONS = Platform.OS === 'android' ? [
@@ -19,84 +28,57 @@ const REQUIRED_PERMISSIONS = Platform.OS === 'android' ? [
19
28
  export async function ensureAndroidPermissions() {
20
29
  if (Platform.OS !== 'android') return true;
21
30
  const result = await PermissionsAndroid.requestMultiple(REQUIRED_PERMISSIONS);
22
- const deniedPermissions = Object.entries(result)
23
- .filter(([_, status]) => status !== PermissionsAndroid.RESULTS.GRANTED)
24
- .map(([perm, _]) => perm);
25
-
26
- if (deniedPermissions.length > 0) {
27
- Alert.alert(
28
- 'Permissions Required',
29
- `The following permissions are still missing: \n${deniedPermissions.join('\n')}`,
30
- [{ text: 'Open Settings', onPress: () => Linking.openSettings() }]
31
- );
32
- return false;
33
- }
34
- return true;
31
+ return Object.values(result).every(status => status === PermissionsAndroid.RESULTS.GRANTED);
35
32
  }
36
33
 
37
34
  export const CallHandler = {
38
-
39
- /**
40
- * @param {string} uuid
41
- * @param {string} number
42
- * @param {string} name
43
- * @param {boolean} hasVideo
44
- * @param {boolean} shouldRing - NEW: Controls native ringtone/vibration
45
- */
46
35
  displayCall: async (uuid, number, name, hasVideo = false, shouldRing = true) => {
47
- if (!CallModule) {
48
- console.log("CallModule is null. Check native linking.");
49
- return false;
50
- }
36
+ if (!CallModule) return false;
51
37
 
52
- // 1. Android Specific Checks
53
38
  if (Platform.OS === 'android') {
54
39
  const hasPerms = await ensureAndroidPermissions();
55
40
  if (!hasPerms) return false;
56
41
 
42
+ // This triggers the "Calling Accounts" system settings if not enabled
57
43
  const isAccountEnabled = await CallModule.checkTelecomPermissions();
58
44
  if (!isAccountEnabled) return false;
59
45
  }
60
46
 
61
- const cleanUuid = uuid.toLowerCase().trim();
62
-
63
- // 2. Cross-platform execution
64
47
  try {
65
- // We now pass 5 arguments to the native side
66
- // uuid, number, name, hasVideo, shouldRing
67
- const success = await CallModule.displayIncomingCall(
68
- cleanUuid,
48
+ return await CallModule.displayIncomingCall(
49
+ uuid.toLowerCase().trim(),
69
50
  number,
70
51
  name,
71
52
  hasVideo,
72
53
  shouldRing
73
54
  );
74
- return success;
75
55
  } catch (e) {
76
- console.log("Native Call Error:", e);
56
+ console.error("Native Call Error:", e);
77
57
  return false;
78
58
  }
79
59
  },
80
60
 
81
61
  destroyNativeCallUI: (uuid) => {
82
- if (CallModule && CallModule.endNativeCall) {
62
+ if (CallModule?.endNativeCall) {
83
63
  CallModule.endNativeCall(uuid.toLowerCase());
84
64
  }
85
65
  },
86
66
 
87
67
  subscribe: (onAccept, onReject, onFailed) => {
88
- if (!callEventEmitter) {
89
- return () => { };
90
- }
68
+ if (!callEventEmitter) return () => { };
91
69
 
92
- const acceptSub = callEventEmitter.addListener('onCallAccepted', (data) => onAccept(data));
93
- const rejectSub = callEventEmitter.addListener('onCallRejected', (data) => onReject(data));
94
- const failSub = onFailed ? callEventEmitter.addListener('onCallFailed', (data) => onFailed(data)) : null;
70
+ const subs = [
71
+ callEventEmitter.addListener('onCallAccepted', onAccept),
72
+ callEventEmitter.addListener('onCallRejected', onReject),
73
+ ];
95
74
 
96
- return () => {
97
- acceptSub.remove();
98
- rejectSub.remove();
99
- if (failSub) failSub.remove();
100
- };
75
+ if (onFailed) {
76
+ subs.push(callEventEmitter.addListener('onCallFailed', onFailed));
77
+ }
78
+
79
+ return () => subs.forEach(s => s.remove());
101
80
  }
102
- };
81
+ };
82
+
83
+ // IMPORTANT: Exporting as default ensures "import CallHandler from '...'" works
84
+ export default CallHandler;
package/package.json CHANGED
@@ -1,9 +1,19 @@
1
1
  {
2
2
  "name": "rns-nativecall",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Raiidr nativecall component with native Android/iOS for handling native call ui, when app is not open or open.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
7
+ "homepage": "https://github.com/raiidr/rns-nativecall",
8
+ "license": "MIT",
9
+ "author": {
10
+ "name": "Your Name",
11
+ "email": "your.email@example.com"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/raiidr/rns-nativecall.git"
16
+ },
7
17
  "react-native": "index.js",
8
18
  "scripts": {
9
19
  "p": "npm publish --access public"
@@ -20,11 +30,7 @@
20
30
  "native",
21
31
  "call keep",
22
32
  "android",
23
- "expo",
24
- "incognito",
25
- "dialog suppression",
26
- "keyboard stability",
27
- "lifecycle events"
33
+ "expo"
28
34
  ],
29
35
  "files": [
30
36
  "android",