@capgo/capacitor-stream-call 0.0.5 → 0.0.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.
|
@@ -63,6 +63,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
63
63
|
private var savedActivity: Activity? = null
|
|
64
64
|
private var savedActivityPaused = false
|
|
65
65
|
private var savedCallsToEndOnResume = mutableListOf<Call>()
|
|
66
|
+
private val callStates: MutableMap<String, CallState> = mutableMapOf()
|
|
66
67
|
|
|
67
68
|
private enum class State {
|
|
68
69
|
NOT_INITIALIZED,
|
|
@@ -342,7 +343,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
342
343
|
SecureUserRepository.getInstance(context).save(credentials)
|
|
343
344
|
|
|
344
345
|
// Initialize Stream Video with new credentials
|
|
345
|
-
if (!hadSavedCredentials || (savedCredentials!!.user.id
|
|
346
|
+
if (!hadSavedCredentials || (savedCredentials!!.user.id != userId)) {
|
|
346
347
|
initializeStreamVideo()
|
|
347
348
|
}
|
|
348
349
|
|
|
@@ -560,89 +561,152 @@ public class StreamCallPlugin : Plugin() {
|
|
|
560
561
|
client.subscribe { event: VideoEvent ->
|
|
561
562
|
android.util.Log.v("StreamCallPlugin", "Received an event ${event.getEventType()} $event")
|
|
562
563
|
when (event) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
ringtonePlayer?.stopRinging()
|
|
576
|
-
// Hide incoming call view if visible
|
|
577
|
-
incomingCallView?.isVisible = false
|
|
578
|
-
}
|
|
564
|
+
// Handle CallCreatedEvent differently - only log it but don't try to access members yet
|
|
565
|
+
is org.openapitools.client.models.CallCreatedEvent -> {
|
|
566
|
+
val callCid = event.call.cid
|
|
567
|
+
android.util.Log.d("StreamCallPlugin", "Call created: $callCid")
|
|
568
|
+
|
|
569
|
+
// let's get the members
|
|
570
|
+
val callParticipants = event.members.filter{ it.user.id != this@StreamCallPlugin.streamVideoClient?.userId } .map { it.user.id }
|
|
571
|
+
android.util.Log.d("StreamCallPlugin", "Call created for $callCid with ${callParticipants.size} participants")
|
|
572
|
+
|
|
573
|
+
// Start tracking this call now that we have the member list
|
|
574
|
+
startCallTimeoutMonitor(callCid, callParticipants)
|
|
575
|
+
|
|
579
576
|
val data = JSObject().apply {
|
|
580
|
-
put("callId",
|
|
581
|
-
put("state", "
|
|
577
|
+
put("callId", callCid)
|
|
578
|
+
put("state", "created")
|
|
582
579
|
}
|
|
583
580
|
notifyListeners("callEvent", data)
|
|
584
581
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
CallOverlayView(
|
|
590
|
-
context = context,
|
|
591
|
-
streamVideo = streamVideoClient,
|
|
592
|
-
call = null
|
|
593
|
-
)
|
|
594
|
-
}
|
|
595
|
-
overlayView?.isVisible = false
|
|
596
|
-
// Stop ringtone if it's still playing
|
|
597
|
-
ringtonePlayer?.stopRinging()
|
|
598
|
-
// Hide incoming call view if visible
|
|
599
|
-
incomingCallView?.isVisible = false
|
|
600
|
-
}
|
|
582
|
+
// Add handler for CallSessionStartedEvent which contains participant information
|
|
583
|
+
is org.openapitools.client.models.CallSessionStartedEvent -> {
|
|
584
|
+
val callCid = event.call.cid
|
|
585
|
+
|
|
601
586
|
val data = JSObject().apply {
|
|
602
|
-
put("callId",
|
|
603
|
-
put("state", "
|
|
587
|
+
put("callId", callCid)
|
|
588
|
+
put("state", "session_started")
|
|
604
589
|
}
|
|
605
590
|
notifyListeners("callEvent", data)
|
|
606
591
|
}
|
|
592
|
+
|
|
607
593
|
is CallRejectedEvent -> {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
call = null
|
|
615
|
-
)
|
|
616
|
-
}
|
|
617
|
-
overlayView?.isVisible = false
|
|
618
|
-
|
|
619
|
-
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
|
620
|
-
if (keyguardManager.isKeyguardLocked) {
|
|
621
|
-
android.util.Log.d("StreamCallPlugin", "Stop ringing and move to background")
|
|
622
|
-
this@StreamCallPlugin.ringtonePlayer?.stopRinging()
|
|
623
|
-
moveAllActivitiesToBackgroundOrKill(context)
|
|
624
|
-
}
|
|
594
|
+
val userId = event.user.id
|
|
595
|
+
val callCid = event.call.cid
|
|
596
|
+
|
|
597
|
+
// Update call state
|
|
598
|
+
callStates[callCid]?.let { callState ->
|
|
599
|
+
callState.participantResponses[userId] = "rejected"
|
|
625
600
|
}
|
|
601
|
+
|
|
602
|
+
// runOnMainThread {
|
|
603
|
+
// android.util.Log.d("StreamCallPlugin", "Setting overlay invisible due to CallRejectedEvent for call ${event.call.cid}")
|
|
604
|
+
// overlayView?.setContent {
|
|
605
|
+
// CallOverlayView(
|
|
606
|
+
// context = context,
|
|
607
|
+
// streamVideo = streamVideoClient,
|
|
608
|
+
// call = null
|
|
609
|
+
// )
|
|
610
|
+
// }
|
|
611
|
+
// overlayView?.isVisible = false
|
|
612
|
+
// }
|
|
613
|
+
|
|
626
614
|
val data = JSObject().apply {
|
|
627
615
|
put("callId", event.call.cid)
|
|
628
616
|
put("state", "rejected")
|
|
617
|
+
put("userId", userId)
|
|
629
618
|
}
|
|
630
619
|
notifyListeners("callEvent", data)
|
|
620
|
+
|
|
621
|
+
// Check if all participants have responded
|
|
622
|
+
checkAllParticipantsResponded(callCid)
|
|
631
623
|
}
|
|
624
|
+
|
|
632
625
|
is CallMissedEvent -> {
|
|
626
|
+
val userId = event.user.id
|
|
627
|
+
val callCid = event.call.cid
|
|
628
|
+
|
|
629
|
+
// Update call state
|
|
630
|
+
callStates[callCid]?.let { callState ->
|
|
631
|
+
callState.participantResponses[userId] = "missed"
|
|
632
|
+
}
|
|
633
|
+
|
|
633
634
|
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
|
634
635
|
if (keyguardManager.isKeyguardLocked) {
|
|
635
636
|
android.util.Log.d("StreamCallPlugin", "Stop ringing and move to background")
|
|
636
637
|
this.ringtonePlayer?.stopRinging()
|
|
637
638
|
moveAllActivitiesToBackgroundOrKill(context)
|
|
638
639
|
}
|
|
640
|
+
|
|
641
|
+
val data = JSObject().apply {
|
|
642
|
+
put("callId", callCid)
|
|
643
|
+
put("state", "missed")
|
|
644
|
+
put("userId", userId)
|
|
645
|
+
}
|
|
646
|
+
notifyListeners("callEvent", data)
|
|
647
|
+
|
|
648
|
+
// Check if all participants have responded
|
|
649
|
+
checkAllParticipantsResponded(callCid)
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
is CallAcceptedEvent -> {
|
|
653
|
+
val userId = event.user.id
|
|
654
|
+
val callCid = event.call.cid
|
|
655
|
+
|
|
656
|
+
// Update call state
|
|
657
|
+
callStates[callCid]?.let { callState ->
|
|
658
|
+
callState.participantResponses[userId] = "accepted"
|
|
659
|
+
|
|
660
|
+
// Since someone accepted, cancel the timeout timer
|
|
661
|
+
android.util.Log.d("StreamCallPlugin", "Call accepted by $userId, canceling timeout timer for $callCid")
|
|
662
|
+
callState.timer?.removeCallbacksAndMessages(null)
|
|
663
|
+
callState.timer = null
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
val data = JSObject().apply {
|
|
667
|
+
put("callId", callCid)
|
|
668
|
+
put("state", "accepted")
|
|
669
|
+
put("userId", userId)
|
|
670
|
+
}
|
|
671
|
+
notifyListeners("callEvent", data)
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
is CallEndedEvent -> {
|
|
675
|
+
runOnMainThread {
|
|
676
|
+
android.util.Log.d("StreamCallPlugin", "Setting overlay invisible due to CallEndedEvent for call ${event.call.cid}")
|
|
677
|
+
// Clean up call resources
|
|
678
|
+
val callCid = event.call.cid
|
|
679
|
+
cleanupCall(callCid)
|
|
680
|
+
}
|
|
681
|
+
val data = JSObject().apply {
|
|
682
|
+
put("callId", event.call.cid)
|
|
683
|
+
put("state", "left")
|
|
684
|
+
}
|
|
685
|
+
notifyListeners("callEvent", data)
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
is CallSessionEndedEvent -> {
|
|
689
|
+
runOnMainThread {
|
|
690
|
+
android.util.Log.d("StreamCallPlugin", "Setting overlay invisible due to CallSessionEndedEvent for call ${event.call.cid}")
|
|
691
|
+
// Clean up call resources
|
|
692
|
+
val callCid = event.call.cid
|
|
693
|
+
cleanupCall(callCid)
|
|
694
|
+
}
|
|
695
|
+
val data = JSObject().apply {
|
|
696
|
+
put("callId", event.call.cid)
|
|
697
|
+
put("state", "left")
|
|
698
|
+
}
|
|
699
|
+
notifyListeners("callEvent", data)
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
else -> {
|
|
703
|
+
val data = JSObject().apply {
|
|
704
|
+
put("callId", streamVideoClient?.state?.activeCall?.value?.cid)
|
|
705
|
+
put("state", event.getEventType())
|
|
706
|
+
}
|
|
707
|
+
notifyListeners("callEvent", data)
|
|
639
708
|
}
|
|
640
709
|
}
|
|
641
|
-
val data = JSObject().apply {
|
|
642
|
-
put("callId", streamVideoClient?.state?.activeCall?.value?.cid)
|
|
643
|
-
put("state", event.getEventType())
|
|
644
|
-
}
|
|
645
|
-
notifyListeners("callEvent", data)
|
|
646
710
|
}
|
|
647
711
|
|
|
648
712
|
// Add call state subscription using collect
|
|
@@ -1015,6 +1079,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1015
1079
|
val callType = call.getString("type") ?: "default"
|
|
1016
1080
|
val shouldRing = call.getBoolean("ring") ?: true
|
|
1017
1081
|
val callId = java.util.UUID.randomUUID().toString()
|
|
1082
|
+
val callCid = "$callType:$callId"
|
|
1018
1083
|
|
|
1019
1084
|
android.util.Log.d("StreamCallPlugin", "Creating call:")
|
|
1020
1085
|
android.util.Log.d("StreamCallPlugin", "- Call ID: $callId")
|
|
@@ -1027,59 +1092,10 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1027
1092
|
try {
|
|
1028
1093
|
// Create the call object
|
|
1029
1094
|
val streamCall = streamVideoClient?.call(type = callType, id = callId)
|
|
1030
|
-
|
|
1031
|
-
//
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
// Subscribe to call events for this specific call
|
|
1036
|
-
streamCall?.subscribe { event ->
|
|
1037
|
-
when (event) {
|
|
1038
|
-
is CallRejectedEvent -> {
|
|
1039
|
-
val userId = event.user.id
|
|
1040
|
-
android.util.Log.d("StreamCallPlugin", "Call was rejected by user: $userId")
|
|
1041
|
-
participantResponses[userId] = "rejected"
|
|
1042
|
-
|
|
1043
|
-
val data = JSObject().apply {
|
|
1044
|
-
put("callId", callId)
|
|
1045
|
-
put("state", "rejected")
|
|
1046
|
-
put("userId", userId)
|
|
1047
|
-
}
|
|
1048
|
-
notifyListeners("callEvent", data)
|
|
1049
|
-
|
|
1050
|
-
// Check if all participants have rejected or missed
|
|
1051
|
-
checkAllParticipantsResponded(participantResponses, totalParticipants, streamCall)
|
|
1052
|
-
}
|
|
1053
|
-
is CallMissedEvent -> {
|
|
1054
|
-
val userId = event.user.id
|
|
1055
|
-
android.util.Log.d("StreamCallPlugin", "Call was missed by user: $userId")
|
|
1056
|
-
participantResponses[userId] = "missed"
|
|
1057
|
-
|
|
1058
|
-
val data = JSObject().apply {
|
|
1059
|
-
put("callId", callId)
|
|
1060
|
-
put("state", "missed")
|
|
1061
|
-
put("userId", userId)
|
|
1062
|
-
}
|
|
1063
|
-
notifyListeners("callEvent", data)
|
|
1064
|
-
|
|
1065
|
-
// Check if all participants have rejected or missed
|
|
1066
|
-
checkAllParticipantsResponded(participantResponses, totalParticipants, streamCall)
|
|
1067
|
-
}
|
|
1068
|
-
is CallAcceptedEvent -> {
|
|
1069
|
-
val userId = event.user.id
|
|
1070
|
-
android.util.Log.d("StreamCallPlugin", "Call was accepted by user: $userId")
|
|
1071
|
-
participantResponses[userId] = "accepted"
|
|
1072
|
-
|
|
1073
|
-
val data = JSObject().apply {
|
|
1074
|
-
put("callId", callId)
|
|
1075
|
-
put("state", "accepted")
|
|
1076
|
-
put("userId", userId)
|
|
1077
|
-
}
|
|
1078
|
-
notifyListeners("callEvent", data)
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1095
|
+
|
|
1096
|
+
// Note: We no longer start tracking here - we'll wait for CallSessionStartedEvent
|
|
1097
|
+
// instead, which contains the actual participant list
|
|
1098
|
+
|
|
1083
1099
|
android.util.Log.d("StreamCallPlugin", "Creating call with members...")
|
|
1084
1100
|
// Create the call with all members
|
|
1085
1101
|
streamCall?.create(
|
|
@@ -1115,40 +1131,158 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1115
1131
|
}
|
|
1116
1132
|
}
|
|
1117
1133
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1134
|
+
private fun startCallTimeoutMonitor(callCid: String, memberIds: List<String>) {
|
|
1135
|
+
val callState = CallState(members = memberIds)
|
|
1136
|
+
|
|
1137
|
+
val handler = Handler(Looper.getMainLooper())
|
|
1138
|
+
val timeoutRunnable = object : Runnable {
|
|
1139
|
+
override fun run() {
|
|
1140
|
+
checkCallTimeout(callCid)
|
|
1141
|
+
handler.postDelayed(this, 1000)
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
handler.postDelayed(timeoutRunnable, 1000)
|
|
1146
|
+
callState.timer = handler
|
|
1147
|
+
|
|
1148
|
+
callStates[callCid] = callState
|
|
1149
|
+
|
|
1150
|
+
android.util.Log.d("StreamCallPlugin", "Started timeout monitor for call $callCid with ${memberIds.size} members")
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
private fun checkCallTimeout(callCid: String) {
|
|
1154
|
+
val callState = callStates[callCid] ?: return
|
|
1155
|
+
|
|
1156
|
+
val now = System.currentTimeMillis()
|
|
1157
|
+
val elapsedSeconds = (now - callState.createdAt) / 1000
|
|
1158
|
+
|
|
1159
|
+
if (elapsedSeconds >= 30) {
|
|
1160
|
+
android.util.Log.d("StreamCallPlugin", "Call $callCid has timed out after $elapsedSeconds seconds")
|
|
1161
|
+
|
|
1162
|
+
val hasAccepted = callState.participantResponses.values.any { it == "accepted" }
|
|
1163
|
+
|
|
1164
|
+
if (!hasAccepted) {
|
|
1165
|
+
android.util.Log.d("StreamCallPlugin", "No one accepted call $callCid, marking all non-responders as missed")
|
|
1128
1166
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
)
|
|
1167
|
+
// First, remove the timer to prevent further callbacks
|
|
1168
|
+
callState.timer?.removeCallbacksAndMessages(null)
|
|
1169
|
+
callState.timer = null
|
|
1170
|
+
|
|
1171
|
+
callState.members.forEach { memberId ->
|
|
1172
|
+
if (memberId !in callState.participantResponses) {
|
|
1173
|
+
callState.participantResponses[memberId] = "missed"
|
|
1174
|
+
|
|
1175
|
+
val data = JSObject().apply {
|
|
1176
|
+
put("callId", callCid)
|
|
1177
|
+
put("state", "missed")
|
|
1178
|
+
put("userId", memberId)
|
|
1139
1179
|
}
|
|
1140
|
-
|
|
1180
|
+
notifyListeners("callEvent", data)
|
|
1141
1181
|
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
val callIdParts = callCid.split(":")
|
|
1185
|
+
if (callIdParts.size >= 2) {
|
|
1186
|
+
val callType = callIdParts[0]
|
|
1187
|
+
val callId = callIdParts[1]
|
|
1142
1188
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1189
|
+
streamVideoClient?.call(type = callType, id = callId)?.let { call ->
|
|
1190
|
+
kotlinx.coroutines.GlobalScope.launch {
|
|
1191
|
+
try {
|
|
1192
|
+
// Use endCallRaw instead of manual cleanup
|
|
1193
|
+
endCallRaw(call)
|
|
1194
|
+
|
|
1195
|
+
// Clean up state - we don't need to do this in endCallRaw because we already did it here
|
|
1196
|
+
callStates.remove(callCid)
|
|
1197
|
+
|
|
1198
|
+
// Notify that call has ended
|
|
1199
|
+
val data = JSObject().apply {
|
|
1200
|
+
put("callId", callCid)
|
|
1201
|
+
put("state", "ended")
|
|
1202
|
+
put("reason", "timeout")
|
|
1203
|
+
}
|
|
1204
|
+
notifyListeners("callEvent", data)
|
|
1205
|
+
} catch (e: Exception) {
|
|
1206
|
+
android.util.Log.e("StreamCallPlugin", "Error ending timed out call", e)
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
private fun cleanupCall(callCid: String) {
|
|
1216
|
+
// Get the call state
|
|
1217
|
+
val callState = callStates[callCid]
|
|
1218
|
+
|
|
1219
|
+
if (callState != null) {
|
|
1220
|
+
// Ensure timer is properly canceled
|
|
1221
|
+
android.util.Log.d("StreamCallPlugin", "Stopping timer for call: $callCid")
|
|
1222
|
+
callState.timer?.removeCallbacksAndMessages(null)
|
|
1223
|
+
callState.timer = null
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
// Remove from callStates
|
|
1227
|
+
callStates.remove(callCid)
|
|
1228
|
+
|
|
1229
|
+
// Hide UI elements directly without setting content
|
|
1230
|
+
runOnMainThread {
|
|
1231
|
+
android.util.Log.d("StreamCallPlugin", "Hiding UI elements for call $callCid (one-time cleanup)")
|
|
1232
|
+
overlayView?.isVisible = false
|
|
1233
|
+
ringtonePlayer?.stopRinging()
|
|
1234
|
+
incomingCallView?.isVisible = false
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
android.util.Log.d("StreamCallPlugin", "Cleaned up resources for ended call: $callCid")
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
private fun checkAllParticipantsResponded(callCid: String) {
|
|
1241
|
+
val callState = callStates[callCid] ?: return
|
|
1242
|
+
|
|
1243
|
+
val totalParticipants = callState.members.size
|
|
1244
|
+
val responseCount = callState.participantResponses.size
|
|
1245
|
+
|
|
1246
|
+
android.util.Log.d("StreamCallPlugin", "Checking responses for call $callCid: $responseCount / $totalParticipants")
|
|
1247
|
+
|
|
1248
|
+
val allResponded = responseCount >= totalParticipants
|
|
1249
|
+
val allRejectedOrMissed = allResponded &&
|
|
1250
|
+
callState.participantResponses.values.all { it == "rejected" || it == "missed" }
|
|
1251
|
+
|
|
1252
|
+
if (allResponded && allRejectedOrMissed) {
|
|
1253
|
+
android.util.Log.d("StreamCallPlugin", "All participants have rejected or missed the call $callCid")
|
|
1254
|
+
|
|
1255
|
+
// Cancel the timer immediately to prevent further callbacks
|
|
1256
|
+
callState.timer?.removeCallbacksAndMessages(null)
|
|
1257
|
+
callState.timer = null
|
|
1258
|
+
|
|
1259
|
+
// End the call using endCallRaw
|
|
1260
|
+
val callIdParts = callCid.split(":")
|
|
1261
|
+
if (callIdParts.size >= 2) {
|
|
1262
|
+
val callType = callIdParts[0]
|
|
1263
|
+
val callId = callIdParts[1]
|
|
1264
|
+
|
|
1265
|
+
streamVideoClient?.call(type = callType, id = callId)?.let { call ->
|
|
1266
|
+
kotlinx.coroutines.GlobalScope.launch {
|
|
1267
|
+
try {
|
|
1268
|
+
// Use endCallRaw instead of manual cleanup
|
|
1269
|
+
endCallRaw(call)
|
|
1270
|
+
|
|
1271
|
+
// Clean up state - we don't need to do this in endCallRaw because we already did it here
|
|
1272
|
+
callStates.remove(callCid)
|
|
1273
|
+
|
|
1274
|
+
// Notify that call has ended
|
|
1275
|
+
val data = JSObject().apply {
|
|
1276
|
+
put("callId", callCid)
|
|
1277
|
+
put("state", "ended")
|
|
1278
|
+
put("reason", "all_rejected_or_missed")
|
|
1279
|
+
}
|
|
1280
|
+
notifyListeners("callEvent", data)
|
|
1281
|
+
} catch (e: Exception) {
|
|
1282
|
+
android.util.Log.e("StreamCallPlugin", "Error ending call after all rejected/missed", e)
|
|
1283
|
+
}
|
|
1147
1284
|
}
|
|
1148
|
-
notifyListeners("callEvent", data)
|
|
1149
1285
|
}
|
|
1150
|
-
} catch (e: Exception) {
|
|
1151
|
-
android.util.Log.e("StreamCallPlugin", "Error checking participant responses: ${e.message}")
|
|
1152
1286
|
}
|
|
1153
1287
|
}
|
|
1154
1288
|
}
|
|
@@ -1215,4 +1349,11 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1215
1349
|
android.util.Log.e("StreamCallPlugin", "Error in magicDeviceDelete", e)
|
|
1216
1350
|
}
|
|
1217
1351
|
}
|
|
1352
|
+
|
|
1353
|
+
data class CallState(
|
|
1354
|
+
val members: List<String>,
|
|
1355
|
+
val participantResponses: MutableMap<String, String> = mutableMapOf(),
|
|
1356
|
+
val createdAt: Long = System.currentTimeMillis(),
|
|
1357
|
+
var timer: Handler? = null
|
|
1358
|
+
)
|
|
1218
1359
|
}
|
package/package.json
CHANGED