rns-nativecall 0.1.3 → 0.1.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.
@@ -1,4 +1,4 @@
1
- ///Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallModule.kt
1
+ /// Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallModule.kt
2
2
  package com.rnsnativecall
3
3
 
4
4
  import android.content.ComponentName
@@ -6,10 +6,10 @@ import android.content.Context
6
6
  import android.content.Intent
7
7
  import android.net.Uri
8
8
  import android.os.Bundle
9
+ import android.telecom.DisconnectCause
9
10
  import android.telecom.PhoneAccount
10
11
  import android.telecom.PhoneAccountHandle
11
12
  import android.telecom.TelecomManager
12
- import android.telecom.DisconnectCause
13
13
  import com.facebook.react.bridge.*
14
14
  import com.facebook.react.modules.core.DeviceEventManagerModule
15
15
 
@@ -29,47 +29,56 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
29
29
  }
30
30
 
31
31
  private fun registerPhoneAccount() {
32
- val telecomManager = reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
32
+ val telecomManager =
33
+ reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
33
34
  val phoneAccountHandle = getPhoneAccountHandle()
34
35
 
35
36
  // Dynamically get the app's display name from the Android Manifest
36
- val appName = reactApplicationContext.applicationInfo.loadLabel(reactApplicationContext.packageManager).toString()
37
+ val appName =
38
+ reactApplicationContext
39
+ .applicationInfo
40
+ .loadLabel(reactApplicationContext.packageManager)
41
+ .toString()
37
42
 
38
43
  // Correct bitmasking: Combine all capabilities into a single integer
39
- val capabilities = PhoneAccount.CAPABILITY_VIDEO_CALLING or
40
- PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING
44
+ val capabilities =
45
+ PhoneAccount.CAPABILITY_VIDEO_CALLING or
46
+ PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING
41
47
 
42
- val phoneAccount = PhoneAccount.builder(phoneAccountHandle, appName)
43
- .setCapabilities(capabilities)
44
- .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
45
- .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
46
- .build()
48
+ val phoneAccount =
49
+ PhoneAccount.builder(phoneAccountHandle, appName)
50
+ .setCapabilities(capabilities)
51
+ .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
52
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
53
+ .build()
47
54
 
48
55
  telecomManager.registerPhoneAccount(phoneAccount)
49
56
  }
50
57
 
51
58
  @ReactMethod
52
59
  fun displayIncomingCall(
53
- uuid: String,
54
- number: String,
55
- name: String,
56
- hasVideo: Boolean,
57
- playRing: Boolean,
58
- promise: Promise
60
+ uuid: String,
61
+ number: String,
62
+ name: String,
63
+ hasVideo: Boolean,
64
+ playRing: Boolean,
65
+ promise: Promise
59
66
  ) {
60
- val telecomManager = reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
67
+ val telecomManager =
68
+ reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
61
69
  val phoneAccountHandle = getPhoneAccountHandle()
62
70
 
63
- val extras = Bundle().apply {
64
- putParcelable(
65
- TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
66
- Uri.fromParts("sip", number, null)
67
- )
68
- putString(TelecomManager.EXTRA_CALL_SUBJECT, name)
69
- putString("EXTRA_CALL_UUID", uuid)
70
- putBoolean("EXTRA_PLAY_RING", playRing)
71
- putBoolean(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, hasVideo)
72
- }
71
+ val extras =
72
+ Bundle().apply {
73
+ putParcelable(
74
+ TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
75
+ Uri.fromParts("sip", number, null)
76
+ )
77
+ putString(TelecomManager.EXTRA_CALL_SUBJECT, name)
78
+ putString("EXTRA_CALL_UUID", uuid)
79
+ putBoolean("EXTRA_PLAY_RING", playRing)
80
+ putBoolean(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, hasVideo)
81
+ }
73
82
 
74
83
  try {
75
84
  telecomManager.addNewIncomingCall(phoneAccountHandle, extras)
@@ -91,7 +100,8 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
91
100
 
92
101
  @ReactMethod
93
102
  fun checkTelecomPermissions(promise: Promise) {
94
- val telecomManager = reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
103
+ val telecomManager =
104
+ reactApplicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
95
105
  val phoneAccountHandle = getPhoneAccountHandle()
96
106
 
97
107
  val account = telecomManager.getPhoneAccount(phoneAccountHandle)
@@ -113,12 +123,10 @@ class CallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
113
123
  private var instance: CallModule? = null
114
124
 
115
125
  fun sendEventToJS(eventName: String, uuid: String?) {
116
- val params = Arguments.createMap().apply {
117
- putString("callUUID", uuid)
118
- }
126
+ val params = Arguments.createMap().apply { putString("callUUID", uuid) }
119
127
  instance?.reactApplicationContext
120
- ?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
121
- ?.emit(eventName, params)
128
+ ?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
129
+ ?.emit(eventName, params)
122
130
  }
123
131
  }
124
- }
132
+ }
@@ -1,4 +1,4 @@
1
- /////Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallPackage.kt
1
+ ///// Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/CallPackage.kt
2
2
  package com.rnsnativecall
3
3
 
4
4
  import com.facebook.react.ReactPackage
@@ -11,7 +11,9 @@ class CallPackage : ReactPackage {
11
11
  return listOf(CallModule(reactContext))
12
12
  }
13
13
 
14
- override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
14
+ override fun createViewManagers(
15
+ reactContext: ReactApplicationContext
16
+ ): List<ViewManager<*, *>> {
15
17
  return emptyList()
16
18
  }
17
- }
19
+ }
@@ -1,4 +1,5 @@
1
- /////Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/MyCallConnection.kt
1
+ /////
2
+ // Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/MyCallConnection.kt
2
3
  package com.rnsnativecall
3
4
 
4
5
  import android.content.Context
@@ -10,11 +11,11 @@ import android.telecom.Connection
10
11
  import android.telecom.DisconnectCause
11
12
 
12
13
  class MyCallConnection(
13
- private val context: Context,
14
- private val callUUID: String?,
15
- private val playRing: Boolean,
16
- private val onAcceptCallback: (String?) -> Unit,
17
- private val onRejectCallback: (String?) -> Unit
14
+ private val context: Context,
15
+ private val callUUID: String?,
16
+ private val playRing: Boolean,
17
+ private val onAcceptCallback: (String?) -> Unit,
18
+ private val onRejectCallback: (String?) -> Unit
18
19
  ) : Connection() {
19
20
 
20
21
  private var mediaPlayer: MediaPlayer? = null
@@ -31,18 +32,19 @@ class MyCallConnection(
31
32
  private fun startRingtone() {
32
33
  val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
33
34
 
34
- mediaPlayer = MediaPlayer().apply {
35
- setDataSource(context, uri)
36
- setAudioAttributes(
37
- AudioAttributes.Builder()
38
- .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
39
- .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
40
- .build()
41
- )
42
- isLooping = true
43
- prepare()
44
- start()
45
- }
35
+ mediaPlayer =
36
+ MediaPlayer().apply {
37
+ setDataSource(context, uri)
38
+ setAudioAttributes(
39
+ AudioAttributes.Builder()
40
+ .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
41
+ .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
42
+ .build()
43
+ )
44
+ isLooping = true
45
+ prepare()
46
+ start()
47
+ }
46
48
  }
47
49
 
48
50
  private fun stopRingtone() {
@@ -1,6 +1,6 @@
1
- /////Users/bush/Desktop/Apps/Raiidr/package/android/src/main/java/com/rnsnativecall/MyConnectionService.kt
2
1
  package com.rnsnativecall
3
2
 
3
+ import android.net.Uri // <--- ADD THIS IMPORT
4
4
  import android.telecom.Connection
5
5
  import android.telecom.ConnectionRequest
6
6
  import android.telecom.ConnectionService
@@ -23,46 +23,53 @@ class MyConnectionService : ConnectionService() {
23
23
  }
24
24
 
25
25
  override fun onCreateIncomingConnection(
26
- connectionManagerPhoneAccount: PhoneAccountHandle?,
27
- request: ConnectionRequest?
26
+ connectionManagerPhoneAccount: PhoneAccountHandle?,
27
+ request: ConnectionRequest?
28
28
  ): Connection {
29
29
 
30
- // 1️⃣ Read extras FIRST
31
30
  val extras = request?.extras
32
31
  val callUUID = extras?.getString("EXTRA_CALL_UUID")
33
32
  val playRing = extras?.getBoolean("EXTRA_PLAY_RING", true) ?: true
34
- val callerName = extras?.getString(TelecomManager.EXTRA_CALL_SUBJECT)
35
-
36
- // 2️⃣ Create connection
37
- val connection = MyCallConnection(
38
- context = applicationContext,
39
- callUUID = callUUID,
40
- playRing = playRing,
41
- onAcceptCallback = { uuid ->
42
- CallModule.sendEventToJS("onCallAccepted", uuid)
43
- },
44
- onRejectCallback = { uuid ->
45
- CallModule.sendEventToJS("onCallRejected", uuid)
46
- }
47
- )
48
-
49
- // 3️⃣ Set caller display name (THIS FIXES MISALIGNMENT)
50
- callerName?.let {
51
- connection.setCallerDisplayName(
52
- it,
53
- TelecomManager.PRESENTATION_ALLOWED
54
- )
55
- }
56
33
 
57
- // 4️⃣ Standard Telecom setup
34
+ // 1. "John Doe" (Top slot)
35
+ val actualPersonName = extras?.getString("EXTRA_CALLER_NAME") ?: "Someone"
36
+
37
+ // 2. "Raiidr Video Call" (Middle/Number slot)
38
+ val appLabel = extras?.getString(TelecomManager.EXTRA_CALL_SUBJECT) ?: "Incoming Call"
39
+
40
+ val connection =
41
+ MyCallConnection(
42
+ context = applicationContext,
43
+ callUUID = callUUID,
44
+ playRing = playRing,
45
+ onAcceptCallback = { uuid ->
46
+ CallModule.sendEventToJS("onCallAccepted", uuid)
47
+ },
48
+ onRejectCallback = { uuid ->
49
+ CallModule.sendEventToJS("onCallRejected", uuid)
50
+ }
51
+ )
52
+
53
+ // 3. Set the LARGE text on top to the Person's Name
54
+ connection.setCallerDisplayName(actualPersonName, TelecomManager.PRESENTATION_ALLOWED)
55
+
56
+ // 4. Standard Telecom setup
58
57
  connection.connectionCapabilities =
59
- Connection.CAPABILITY_MUTE or Connection.CAPABILITY_SUPPORT_HOLD
58
+ Connection.CAPABILITY_MUTE or Connection.CAPABILITY_SUPPORT_HOLD
59
+
60
+ // --- THE UI FIX ---
61
+ // We force the App Label (e.g. "Raiidr Video Call") into the Address slot
62
+ // This replaces the raw phone number/handle on the incoming call screen.
63
+ val labelUri = Uri.fromParts("tel", appLabel, null)
64
+ connection.setAddress(labelUri, TelecomManager.PRESENTATION_ALLOWED)
60
65
 
61
- connection.setAddress(request?.address, TelecomManager.PRESENTATION_ALLOWED)
62
66
  connection.setInitializing()
63
67
  connection.setRinging()
64
68
 
65
- // 5️⃣ Track connection
69
+ // Emit event to JS so the app can send the 'ringing' status
70
+ callUUID?.let { CallModule.sendEventToJS("onCallDisplayed", it) }
71
+
72
+ // Track connection
66
73
  callUUID?.let { addConnection(it, connection) }
67
74
 
68
75
  return connection
@@ -6,17 +6,34 @@ import android.net.Uri
6
6
  import android.os.Bundle
7
7
  import android.telecom.PhoneAccountHandle
8
8
  import android.telecom.TelecomManager
9
- import android.telecom.VideoProfile // <-- ADD THIS IMPORT
9
+ import android.telecom.VideoProfile
10
10
 
11
11
  object NativeCallManager {
12
12
 
13
13
  fun handleIncomingPush(context: Context, data: Map<String, String>) {
14
14
  val uuid = data["callId"] ?: return
15
15
  val handle = data["from"] ?: "Unknown"
16
+ val callType = data["callType"] ?: "audio"
16
17
  val name = data["name"] ?: handle
17
- val hasVideo = data["hasVideo"]?.toBoolean() ?: false
18
18
  val playRing = data["playRing"]?.toBoolean() ?: true
19
19
 
20
+ // 1. Get Dynamic App Name
21
+ val appName =
22
+ try {
23
+ val pm = context.packageManager
24
+ val ai = pm.getApplicationInfo(context.packageName, 0)
25
+ pm.getApplicationLabel(ai).toString()
26
+ } catch (e: Exception) {
27
+ "App"
28
+ }
29
+
30
+ // 2. Format Sub-label (e.g., "Raiidr Video Call")
31
+ val capitalizedCallType =
32
+ callType.replaceFirstChar {
33
+ if (it.isLowerCase()) it.titlecase() else it.toString()
34
+ }
35
+ val subLabel = "$appName $capitalizedCallType Call"
36
+
20
37
  val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
21
38
  val phoneAccountHandle = getPhoneAccountHandle(context)
22
39
 
@@ -27,15 +44,23 @@ object NativeCallManager {
27
44
  Uri.fromParts("sip", handle, null)
28
45
  )
29
46
  putString("EXTRA_CALL_UUID", uuid)
30
- putString(TelecomManager.EXTRA_CALL_SUBJECT, name)
47
+
48
+ // This goes to the SECONDARY slot in MyConnectionService
49
+ putString(TelecomManager.EXTRA_CALL_SUBJECT, subLabel)
50
+
51
+ // This goes to the PRIMARY slot (The Name) in MyConnectionService
52
+ putString("EXTRA_CALLER_NAME", name)
53
+
31
54
  putBoolean("EXTRA_PLAY_RING", playRing)
32
55
 
33
- // Video state requires specific integer constants
56
+ val isVideo = callType.equals("video", ignoreCase = true)
34
57
  val videoState =
35
- if (hasVideo) VideoProfile.STATE_BIDIRECTIONAL
58
+ if (isVideo) VideoProfile.STATE_BIDIRECTIONAL
36
59
  else VideoProfile.STATE_AUDIO_ONLY
37
-
38
60
  putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState)
61
+
62
+ // Forward all other data
63
+ data.forEach { (key, value) -> putString(key, value) }
39
64
  }
40
65
 
41
66
  try {
@@ -45,6 +70,7 @@ object NativeCallManager {
45
70
  }
46
71
  }
47
72
 
73
+ // This function must be OUTSIDE handleIncomingPush but INSIDE the object
48
74
  private fun getPhoneAccountHandle(context: Context): PhoneAccountHandle {
49
75
  val componentName = ComponentName(context, MyConnectionService::class.java)
50
76
  return PhoneAccountHandle(componentName, "${context.packageName}.voip")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rns-nativecall",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
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",