rns-nativecall 0.7.5 → 0.7.6

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.
@@ -9,46 +9,64 @@ import android.os.Build
9
9
  import android.media.Ringtone
10
10
  import android.media.RingtoneManager
11
11
  import android.graphics.Color
12
-
13
12
  import androidx.core.app.Person
14
13
  import androidx.core.app.NotificationCompat
15
-
16
14
  import android.app.KeyguardManager
17
15
 
18
-
19
16
  object NativeCallManager {
20
17
 
21
18
  private var ringtone: Ringtone? = null
22
19
  const val channelId = "CALL_CHANNEL_ID"
23
20
 
21
+ // ✅ ADDED: stopRingtone definition
22
+ fun stopRingtone() {
23
+ try {
24
+ ringtone?.let { if (it.isPlaying) it.stop() }
25
+ ringtone = null
26
+ } catch (e: Exception) {
27
+ ringtone = null
28
+ }
29
+ }
30
+
31
+ // ✅ ADDED: showMissedCallNotification definition
32
+ fun showMissedCallNotification(context: Context, data: Map<String, String>, uuid: String) {
33
+ val name = data["name"] ?: "Unknown Caller"
34
+ val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
35
+
36
+ val builder = NotificationCompat.Builder(context, channelId)
37
+ .setSmallIcon(context.applicationInfo.icon)
38
+ .setContentTitle("Missed Call")
39
+ .setContentText("Incoming call from $name")
40
+ .setPriority(NotificationCompat.PRIORITY_HIGH)
41
+ .setAutoCancel(true)
42
+
43
+ notificationManager.notify(uuid.hashCode(), builder.build())
44
+ }
45
+
24
46
  fun handleIncomingPush(context: Context, data: Map<String, String>) {
25
47
  val uuid = data["callUuid"] ?: return
26
48
  stopRingtone()
27
49
 
28
50
  val name = data["name"] ?: "Incoming Call"
29
51
  val callType = data["callType"] ?: "audio"
52
+
30
53
  // --- LOCK SCREEN GATEKEEPER ---
31
- val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
32
- if (keyguardManager.isKeyguardLocked) {
33
- // Device is locked? We bounce it!
34
- CallState.markCanceled(uuid, context) // Save to disk so Headless/Splash sees it's invalid
35
- showMissedCallNotification(context, data, uuid)
36
- return // Kill the flow here
37
- }
38
- val notificationId = uuid.hashCode()
54
+ val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
55
+ if (keyguardManager.isKeyguardLocked) {
56
+ // Device is locked? We bounce it!
57
+ CallState.markCanceled(uuid, context)
58
+ showMissedCallNotification(context, data, uuid)
59
+ return // 🛑 Flow stops here
60
+ }
39
61
 
62
+ val notificationId = uuid.hashCode()
40
63
  val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
41
64
  PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
42
65
  } else {
43
66
  PendingIntent.FLAG_UPDATE_CURRENT
44
67
  }
45
68
 
46
- val noOpIntent = PendingIntent.getActivity(
47
- context,
48
- notificationId + 1,
49
- Intent(),
50
- pendingFlags
51
- )
69
+ val noOpIntent = PendingIntent.getActivity(context, notificationId + 1, Intent(), pendingFlags)
52
70
 
53
71
  val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
54
72
  this.action = "ACTION_SHOW_UI_$uuid"
@@ -56,12 +74,7 @@ object NativeCallManager {
56
74
  this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
57
75
  }
58
76
 
59
- val fullScreenPendingIntent = PendingIntent.getActivity(
60
- context,
61
- notificationId,
62
- intentToActivity,
63
- pendingFlags
64
- )
77
+ val fullScreenPendingIntent = PendingIntent.getActivity(context, notificationId, intentToActivity, pendingFlags)
65
78
 
66
79
  val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
67
80
  this.action = "ACTION_REJECT_$uuid"
@@ -69,21 +82,12 @@ object NativeCallManager {
69
82
  data.forEach { (key, value) -> this.putExtra(key, value) }
70
83
  }
71
84
 
72
- val rejectPendingIntent = PendingIntent.getBroadcast(
73
- context,
74
- notificationId,
75
- rejectIntent,
76
- pendingFlags
77
- )
85
+ val rejectPendingIntent = PendingIntent.getBroadcast(context, notificationId, rejectIntent, pendingFlags)
78
86
 
79
87
  val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
80
88
 
81
89
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
82
- val channel = NotificationChannel(
83
- channelId,
84
- "Incoming Calls",
85
- NotificationManager.IMPORTANCE_HIGH // NotificationManager.IMPORTANCE_HIGH
86
- ).apply {
90
+ val channel = NotificationChannel(channelId, "Incoming Calls", NotificationManager.IMPORTANCE_HIGH).apply {
87
91
  enableVibration(true)
88
92
  vibrationPattern = longArrayOf(0, 500, 500, 500)
89
93
  lightColor = Color.GREEN
@@ -98,8 +102,8 @@ object NativeCallManager {
98
102
  .setSmallIcon(context.applicationInfo.icon)
99
103
  .setContentTitle("Incoming $callType call")
100
104
  .setContentText(name)
101
- .setPriority(NotificationCompat.PRIORITY_MAX) // PRIORITY_HIGH
102
- .setCategory(NotificationCompat.CATEGORY_CALL) // CATEGORY_CALL
105
+ .setPriority(NotificationCompat.PRIORITY_MAX)
106
+ .setCategory(NotificationCompat.CATEGORY_CALL)
103
107
  .setOngoing(true)
104
108
  .setAutoCancel(false)
105
109
  .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
@@ -122,145 +126,35 @@ object NativeCallManager {
122
126
  }
123
127
  }
124
128
 
125
- // fun handleIncomingPush(context: Context, data: Map<String, String>) {
126
- // val uuid = data["callUuid"] ?: return
127
- // stopRingtone()
128
-
129
- // val name = data["name"] ?: "Incoming Call"
130
- // val callType = data["callType"] ?: "audio"
131
- // val notificationId = uuid.hashCode()
132
-
133
- // val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
134
- // PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
135
- // } else {
136
- // PendingIntent.FLAG_UPDATE_CURRENT
137
- // }
138
-
139
- // // 1. Setup the Intents
140
- // val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
141
- // this.action = "ACTION_ANSWER_$uuid"
142
- // data.forEach { (key, value) -> this.putExtra(key, value) }
143
- // this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
144
- // }
145
-
146
- // val fullScreenPendingIntent = PendingIntent.getActivity(
147
- // context, notificationId, intentToActivity, pendingFlags
148
- // )
149
-
150
- // val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
151
- // this.action = "ACTION_REJECT_$uuid"
152
- // this.putExtra("EXTRA_CALL_UUID", uuid)
153
- // data.forEach { (key, value) -> this.putExtra(key, value) }
154
- // }
155
-
156
- // // Fix: Define the missing rejectPendingIntent
157
- // val rejectPendingIntent = PendingIntent.getBroadcast(
158
- // context, notificationId, rejectIntent, pendingFlags
159
- // )
160
-
161
- // // 2. Create the Person object for CallStyle
162
- // val caller = Person.Builder()
163
- // .setName(name)
164
- // .setImportant(true)
165
- // .build()
166
-
167
- // val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
168
-
169
- // // 3. Setup Channel
170
- // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
171
- // val channel = NotificationChannel(
172
- // channelId,
173
- // "Incoming Calls",
174
- // NotificationManager.IMPORTANCE_HIGH
175
- // ).apply {
176
- // enableVibration(true)
177
- // vibrationPattern = longArrayOf(0, 500, 500, 500)
178
- // lightColor = Color.GREEN
179
- // setBypassDnd(true)
180
- // setSound(null, null)
181
- // }
182
- // notificationManager.createNotificationChannel(channel)
183
- // }
184
-
185
- // // 4. Build with CallStyle
186
- // val builder = NotificationCompat.Builder(context, channelId)
187
- // .setSmallIcon(context.applicationInfo.icon)
188
- // .setPriority(NotificationCompat.PRIORITY_MAX)
189
- // .setCategory(NotificationCompat.CATEGORY_CALL)
190
- // .setOngoing(true)
191
- // .setAutoCancel(false)
192
- // .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
193
- // .setFullScreenIntent(fullScreenPendingIntent, true)
194
- // .setStyle(
195
- // NotificationCompat.CallStyle.forIncomingCall(
196
- // caller,
197
- // rejectPendingIntent,
198
- // fullScreenPendingIntent
199
- // )
200
- // )
201
-
202
- // notificationManager.notify(notificationId, builder.build())
203
-
204
- // // 5. Start Ringtone
205
- // try {
206
- // val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
207
- // ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
208
- // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
209
- // ringtone?.isLooping = true
210
- // }
211
- // ringtone?.play()
212
- // } catch (e: Exception) {
213
- // e.printStackTrace()
214
- // }
215
- // }
216
-
217
-
218
- // fun stopRingtone() {
219
- // try {
220
- // ringtone?.let { if (it.isPlaying) it.stop() }
221
- // ringtone = null
222
- // } catch (e: Exception) {
223
- // ringtone = null
224
- // }
225
- // }
226
-
227
- fun connecting(context: Context, uuid: String, name: String, callType: String) {
228
- val notificationId = uuid.hashCode()
229
- val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
230
-
231
- val builder = NotificationCompat.Builder(context, channelId)
232
- .setSmallIcon(context.applicationInfo.icon)
233
- .setContentTitle("Incoming $callType call")
234
- .setContentText("Connecting…") // ✅ show connecting text
235
- .setSubText("Connecting…") // status line
236
- .setPriority(NotificationCompat.PRIORITY_MAX)
237
- .setCategory(NotificationCompat.CATEGORY_CALL)
238
- .setOngoing(true)
239
- .setAutoCancel(false)
240
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
241
- .setProgress(0, 0, true) // ✅ system activity indicator (indeterminate progress bar)
242
-
243
- notificationManager.notify(notificationId, builder.build())
244
- }
245
-
246
- fun aborting(context: Context, uuid: String, name: String, callType: String) {
247
- val notificationId = uuid.hashCode()
248
- val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
249
-
250
- val builder = NotificationCompat.Builder(context, channelId)
251
- .setSmallIcon(context.applicationInfo.icon)
252
- .setContentTitle("Incoming $callType call")
253
- .setContentText("Aborting…") // ✅ show aborting text
254
- .setSubText("Aborting…") // status line
255
- .setPriority(NotificationCompat.PRIORITY_MAX)
256
- .setCategory(NotificationCompat.CATEGORY_CALL)
257
- .setOngoing(true)
258
- .setAutoCancel(false)
259
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
260
- .setProgress(0, 0, true) // ✅ indeterminate progress indicator
129
+ fun connecting(context: Context, uuid: String, name: String, callType: String) {
130
+ val notificationId = uuid.hashCode()
131
+ val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
132
+ val builder = NotificationCompat.Builder(context, channelId)
133
+ .setSmallIcon(context.applicationInfo.icon)
134
+ .setContentTitle("Incoming $callType call")
135
+ .setContentText("Connecting…")
136
+ .setPriority(NotificationCompat.PRIORITY_MAX)
137
+ .setCategory(NotificationCompat.CATEGORY_CALL)
138
+ .setOngoing(true)
139
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
140
+ .setProgress(0, 0, true)
141
+ notificationManager.notify(notificationId, builder.build())
142
+ }
261
143
 
262
- notificationManager.notify(notificationId, builder.build())
263
- }
144
+ fun aborting(context: Context, uuid: String, name: String, callType: String) {
145
+ val notificationId = uuid.hashCode()
146
+ val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
147
+ val builder = NotificationCompat.Builder(context, channelId)
148
+ .setSmallIcon(context.applicationInfo.icon)
149
+ .setContentTitle("Incoming $callType call")
150
+ .setContentText("Aborting…")
151
+ .setPriority(NotificationCompat.PRIORITY_MAX)
152
+ .setCategory(NotificationCompat.CATEGORY_CALL)
153
+ .setOngoing(true)
154
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
155
+ .setProgress(0, 0, true)
156
+ notificationManager.notify(notificationId, builder.build())
157
+ }
264
158
 
265
159
  fun dismissIncomingCall(context: Context, uuid: String?) {
266
160
  stopRingtone()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rns-nativecall",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
4
4
  "description": "High-performance React Native module for handling native VoIP call UI on Android and iOS.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",