rns-nativecall 0.0.5 → 0.0.7
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.
|
@@ -22,20 +22,28 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
22
22
|
|
|
23
23
|
override fun getName() = "CallModule"
|
|
24
24
|
|
|
25
|
+
private fun getPhoneAccountHandle(): PhoneAccountHandle {
|
|
26
|
+
val componentName = ComponentName(reactApplicationContext, MyConnectionService::class.java)
|
|
27
|
+
// Using the app's package name for the ID makes it unique for every app using this package
|
|
28
|
+
return PhoneAccountHandle(componentName, "${reactApplicationContext.packageName}.voip")
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
private fun registerPhoneAccount() {
|
|
26
32
|
val telecomManager = reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
27
|
-
val
|
|
28
|
-
val phoneAccountHandle = PhoneAccountHandle(componentName, "RaiidrVoip")
|
|
33
|
+
val phoneAccountHandle = getPhoneAccountHandle()
|
|
29
34
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING
|
|
35
|
+
// Dynamically get the app's display name from the Android Manifest
|
|
36
|
+
val appName = reactApplicationContext.applicationInfo.loadLabel(reactApplicationContext.packageManager).toString()
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
// Correct bitmasking: Combine all capabilities into a single integer
|
|
39
|
+
val capabilities = PhoneAccount.CAPABILITY_VIDEO_CALLING or
|
|
40
|
+
PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING
|
|
41
|
+
|
|
42
|
+
val phoneAccount = PhoneAccount.builder(phoneAccountHandle, appName)
|
|
43
|
+
.setCapabilities(capabilities)
|
|
44
|
+
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
|
|
45
|
+
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
|
|
46
|
+
.build()
|
|
39
47
|
|
|
40
48
|
telecomManager.registerPhoneAccount(phoneAccount)
|
|
41
49
|
}
|
|
@@ -50,8 +58,7 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
50
58
|
promise: Promise
|
|
51
59
|
) {
|
|
52
60
|
val telecomManager = reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
53
|
-
val
|
|
54
|
-
val phoneAccountHandle = PhoneAccountHandle(componentName, "RaiidrVoip")
|
|
61
|
+
val phoneAccountHandle = getPhoneAccountHandle()
|
|
55
62
|
|
|
56
63
|
val extras = Bundle().apply {
|
|
57
64
|
putParcelable(
|
|
@@ -85,13 +92,13 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
85
92
|
@ReactMethod
|
|
86
93
|
fun checkTelecomPermissions(promise: Promise) {
|
|
87
94
|
val telecomManager = reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
88
|
-
val
|
|
89
|
-
val phoneAccountHandle = PhoneAccountHandle(componentName, "RaiidrVoip")
|
|
95
|
+
val phoneAccountHandle = getPhoneAccountHandle()
|
|
90
96
|
|
|
91
97
|
val account = telecomManager.getPhoneAccount(phoneAccountHandle)
|
|
92
98
|
if (account != null && account.isEnabled) {
|
|
93
99
|
promise.resolve(true)
|
|
94
100
|
} else {
|
|
101
|
+
// Opens the system settings for "Calling Accounts" so the user can enable the app
|
|
95
102
|
val intent = Intent(TelecomManager.ACTION_CHANGE_PHONE_ACCOUNTS)
|
|
96
103
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
97
104
|
reactApplicationContext.startActivity(intent)
|
|
@@ -114,4 +121,4 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
114
121
|
?.emit(eventName, params)
|
|
115
122
|
}
|
|
116
123
|
}
|
|
117
|
-
}
|
|
124
|
+
}
|
package/ios/CallModule.m
CHANGED
|
@@ -11,20 +11,22 @@ RCT_EXPORT_MODULE();
|
|
|
11
11
|
- (instancetype)init {
|
|
12
12
|
self = [super init];
|
|
13
13
|
if (self) {
|
|
14
|
+
// Dynamically get the App Name from the bundle so it's not hardcoded
|
|
15
|
+
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
|
|
16
|
+
if (!appName) {
|
|
17
|
+
appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
#pragma clang diagnostic push
|
|
15
21
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
16
|
-
CXProviderConfiguration *config = [[CXProviderConfiguration alloc] initWithLocalizedName
|
|
22
|
+
CXProviderConfiguration *config = [[CXProviderConfiguration alloc] initWithLocalizedName:appName];
|
|
17
23
|
#pragma clang diagnostic pop
|
|
18
24
|
|
|
19
25
|
config.supportsVideo = YES;
|
|
20
26
|
config.maximumCallGroups = 1;
|
|
21
27
|
config.maximumCallsPerCallGroup = 1;
|
|
22
28
|
config.supportedHandleTypes = [NSSet setWithObject:@(CXHandleTypeGeneric)];
|
|
23
|
-
config.includesCallsInRecents = NO;
|
|
24
|
-
|
|
25
|
-
// If you had a custom file like "Ringtone.aif" in your project,
|
|
26
|
-
// you would set it here:
|
|
27
|
-
// config.ringtoneSound = @"Ringtone.aif";
|
|
29
|
+
config.includesCallsInRecents = NO;
|
|
28
30
|
|
|
29
31
|
self.provider = [[CXProvider alloc] initWithConfiguration:config];
|
|
30
32
|
[self.provider setDelegate:self queue:nil];
|
|
@@ -32,7 +34,7 @@ RCT_EXPORT_MODULE();
|
|
|
32
34
|
return self;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
//
|
|
37
|
+
// Matches the 5 arguments in your JS/Android implementation
|
|
36
38
|
RCT_EXPORT_METHOD(displayIncomingCall:(NSString *)uuidString
|
|
37
39
|
number:(NSString *)number
|
|
38
40
|
name:(NSString *)name
|
|
@@ -48,12 +50,12 @@ RCT_EXPORT_METHOD(displayIncomingCall:(NSString *)uuidString
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
CXCallUpdate *update = [[CXCallUpdate alloc] init];
|
|
53
|
+
// We use 'name' here so the system UI shows the caller's name instead of just their number
|
|
51
54
|
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:name];
|
|
52
55
|
update.hasVideo = hasVideo;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// However, including it here ensures your JS bridge call matches.
|
|
56
|
+
update.supportsGrouping = NO;
|
|
57
|
+
update.supportsUngrouping = NO;
|
|
58
|
+
update.supportsHolding = NO;
|
|
57
59
|
|
|
58
60
|
[self.provider reportNewIncomingCallWithUUID:uuid
|
|
59
61
|
update:update
|
|
@@ -72,10 +74,15 @@ RCT_EXPORT_METHOD(endNativeCall:(NSString *)uuidString) {
|
|
|
72
74
|
[self.provider reportCallWithUUID:uuid
|
|
73
75
|
endedAtDate:[NSDate date]
|
|
74
76
|
reason:CXCallEndedReasonRemoteEnded];
|
|
75
|
-
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
// Placeholder for Android parity
|
|
81
|
+
RCT_EXPORT_METHOD(checkTelecomPermissions:(RCTPromiseResolveBlock)resolve
|
|
82
|
+
reject:(RCTPromiseResolveBlock)reject) {
|
|
83
|
+
resolve(@YES); // iOS permissions are handled via Info.plist and system prompts
|
|
84
|
+
}
|
|
85
|
+
|
|
79
86
|
// MARK: - CXProviderDelegate
|
|
80
87
|
|
|
81
88
|
- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {
|
|
@@ -92,4 +99,4 @@ RCT_EXPORT_METHOD(endNativeCall:(NSString *)uuidString) {
|
|
|
92
99
|
|
|
93
100
|
- (void)providerDidReset:(CXProvider *)provider { }
|
|
94
101
|
|
|
95
|
-
@end
|
|
102
|
+
@end
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rns-nativecall",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.7",
|
|
4
|
+
"description": "RNS 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
7
|
"homepage": "https://github.com/raiidr/rns-nativecall",
|
package/withRaiidrVoip.js
CHANGED
|
@@ -8,11 +8,10 @@ function withAndroidConfig(config) {
|
|
|
8
8
|
return withAndroidManifest(config, (config) => {
|
|
9
9
|
const manifest = config.modResults;
|
|
10
10
|
|
|
11
|
-
// 1. Add required permissions
|
|
12
11
|
const permissions = [
|
|
13
12
|
'android.permission.READ_PHONE_NUMBERS',
|
|
14
13
|
'android.permission.CALL_PHONE',
|
|
15
|
-
'android.permission.MANAGE_OWN_CALLS'
|
|
14
|
+
'android.permission.MANAGE_OWN_CALLS'
|
|
16
15
|
];
|
|
17
16
|
|
|
18
17
|
if (!manifest.manifest['uses-permission']) {
|
|
@@ -25,7 +24,6 @@ function withAndroidConfig(config) {
|
|
|
25
24
|
}
|
|
26
25
|
});
|
|
27
26
|
|
|
28
|
-
// 2. Add MyConnectionService service
|
|
29
27
|
const application = manifest.manifest.application[0];
|
|
30
28
|
application.service = application.service || [];
|
|
31
29
|
|
|
@@ -69,15 +67,16 @@ function withIosConfig(config) {
|
|
|
69
67
|
}
|
|
70
68
|
});
|
|
71
69
|
|
|
72
|
-
// 2.
|
|
70
|
+
// 2. Dynamic Microphone Description
|
|
71
|
+
// config.name pulls the name from the user's app.json automatically
|
|
72
|
+
const appName = config.name || 'this app';
|
|
73
73
|
infoPlist.NSMicrophoneUsageDescription =
|
|
74
|
-
infoPlist.NSMicrophoneUsageDescription ||
|
|
74
|
+
infoPlist.NSMicrophoneUsageDescription || `Allow ${appName} to access your microphone for calls.`;
|
|
75
75
|
|
|
76
76
|
return config;
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
// Export the combined plugin
|
|
81
80
|
module.exports = (config) => {
|
|
82
81
|
return withPlugins(config, [
|
|
83
82
|
withAndroidConfig,
|