@capgo/capacitor-stream-call 0.0.6 → 0.0.18
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.
- package/CapgoCapacitorStreamCall.podspec +2 -2
- package/Package.swift +1 -1
- package/README.md +265 -11
- package/android/build.gradle +22 -4
- package/android/src/main/java/ee/forgr/capacitor/streamcall/CustomNotificationHandler.kt +2 -2
- package/android/src/main/java/ee/forgr/capacitor/streamcall/StreamCallPlugin.kt +138 -201
- package/dist/docs.json +761 -12
- package/dist/esm/definitions.d.ts +57 -23
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +2 -1
- package/dist/esm/web.js +58 -22
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +58 -22
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +58 -22
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/StreamCallPlugin/StreamCallPlugin.swift +151 -142
- package/ios/Sources/StreamCallPlugin/TouchInterceptView.swift +3 -3
- package/package.json +2 -2
|
@@ -6,6 +6,8 @@ import android.app.Application
|
|
|
6
6
|
import android.app.KeyguardManager
|
|
7
7
|
import android.content.Context
|
|
8
8
|
import android.graphics.Color
|
|
9
|
+
import android.media.RingtoneManager
|
|
10
|
+
import android.net.Uri
|
|
9
11
|
import android.os.Bundle
|
|
10
12
|
import android.os.Handler
|
|
11
13
|
import android.os.Looper
|
|
@@ -20,13 +22,11 @@ import com.getcapacitor.Plugin
|
|
|
20
22
|
import com.getcapacitor.PluginCall
|
|
21
23
|
import com.getcapacitor.PluginMethod
|
|
22
24
|
import com.getcapacitor.annotation.CapacitorPlugin
|
|
23
|
-
import io.getstream.android.push.firebase.FirebasePushDeviceGenerator
|
|
24
25
|
import io.getstream.android.push.permissions.ActivityLifecycleCallbacks
|
|
25
26
|
import io.getstream.video.android.core.Call
|
|
26
27
|
import io.getstream.video.android.core.GEO
|
|
27
28
|
import io.getstream.video.android.core.StreamVideo
|
|
28
29
|
import io.getstream.video.android.core.StreamVideoBuilder
|
|
29
|
-
import io.getstream.video.android.core.model.RejectReason
|
|
30
30
|
import io.getstream.video.android.core.notifications.NotificationConfig
|
|
31
31
|
import io.getstream.video.android.core.notifications.NotificationHandler
|
|
32
32
|
import io.getstream.video.android.core.sounds.emptyRingingConfig
|
|
@@ -35,16 +35,21 @@ import io.getstream.video.android.model.StreamCallId
|
|
|
35
35
|
import io.getstream.video.android.model.User
|
|
36
36
|
import io.getstream.video.android.model.streamCallId
|
|
37
37
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
|
38
|
-
import kotlinx.coroutines.flow.Flow
|
|
39
38
|
import kotlinx.coroutines.launch
|
|
40
|
-
import org.openapitools.client.models.CallAcceptedEvent
|
|
41
|
-
import org.openapitools.client.models.CallEndedEvent
|
|
42
|
-
import org.openapitools.client.models.CallMissedEvent
|
|
43
|
-
import org.openapitools.client.models.CallRejectedEvent
|
|
44
|
-
import org.openapitools.client.models.CallSessionEndedEvent
|
|
45
|
-
import org.openapitools.client.models.VideoEvent
|
|
46
39
|
import io.getstream.video.android.model.Device
|
|
47
|
-
import kotlinx.coroutines.
|
|
40
|
+
import kotlinx.coroutines.tasks.await
|
|
41
|
+
import com.google.firebase.messaging.FirebaseMessaging
|
|
42
|
+
import io.getstream.android.push.PushProvider
|
|
43
|
+
import io.getstream.android.push.firebase.FirebasePushDeviceGenerator
|
|
44
|
+
import io.getstream.android.video.generated.models.CallAcceptedEvent
|
|
45
|
+
import io.getstream.android.video.generated.models.CallCreatedEvent
|
|
46
|
+
import io.getstream.android.video.generated.models.CallEndedEvent
|
|
47
|
+
import io.getstream.android.video.generated.models.CallMissedEvent
|
|
48
|
+
import io.getstream.android.video.generated.models.CallRejectedEvent
|
|
49
|
+
import io.getstream.android.video.generated.models.CallSessionEndedEvent
|
|
50
|
+
import io.getstream.android.video.generated.models.CallSessionStartedEvent
|
|
51
|
+
import io.getstream.android.video.generated.models.VideoEvent
|
|
52
|
+
import io.getstream.video.android.core.sounds.RingingConfig
|
|
48
53
|
|
|
49
54
|
// I am not a religious pearson, but at this point, I am not sure even god himself would understand this code
|
|
50
55
|
// It's a spaghetti-like, tangled, unreadable mess and frankly, I am deeply sorry for the code crimes commited in the Android impl
|
|
@@ -63,7 +68,12 @@ public class StreamCallPlugin : Plugin() {
|
|
|
63
68
|
private var savedActivity: Activity? = null
|
|
64
69
|
private var savedActivityPaused = false
|
|
65
70
|
private var savedCallsToEndOnResume = mutableListOf<Call>()
|
|
66
|
-
private val callStates: MutableMap<String,
|
|
71
|
+
private val callStates: MutableMap<String, LocalCallState> = mutableMapOf()
|
|
72
|
+
|
|
73
|
+
// Store current call info
|
|
74
|
+
private var currentCallId: String = ""
|
|
75
|
+
private var currentCallType: String = ""
|
|
76
|
+
private var currentCallState: String = ""
|
|
67
77
|
|
|
68
78
|
private enum class State {
|
|
69
79
|
NOT_INITIALIZED,
|
|
@@ -71,6 +81,11 @@ public class StreamCallPlugin : Plugin() {
|
|
|
71
81
|
INITIALIZED
|
|
72
82
|
}
|
|
73
83
|
|
|
84
|
+
public fun incomingOnlyRingingConfig(): RingingConfig = object : RingingConfig {
|
|
85
|
+
override val incomingCallSoundUri: Uri? = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
|
86
|
+
override val outgoingCallSoundUri: Uri? = null
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
private fun runOnMainThread(action: () -> Unit) {
|
|
75
90
|
mainHandler.post { action() }
|
|
76
91
|
}
|
|
@@ -211,12 +226,8 @@ public class StreamCallPlugin : Plugin() {
|
|
|
211
226
|
// Stop ringtone
|
|
212
227
|
ringtonePlayer?.stopRinging()
|
|
213
228
|
|
|
214
|
-
// Notify that call has ended
|
|
215
|
-
|
|
216
|
-
put("callId", call.id)
|
|
217
|
-
put("state", "rejected")
|
|
218
|
-
}
|
|
219
|
-
notifyListeners("callEvent", data)
|
|
229
|
+
// Notify that call has ended using our helper
|
|
230
|
+
updateCallStatusAndNotify(call.id, "rejected")
|
|
220
231
|
|
|
221
232
|
hideIncomingCall()
|
|
222
233
|
} catch (e: Exception) {
|
|
@@ -250,14 +261,6 @@ public class StreamCallPlugin : Plugin() {
|
|
|
250
261
|
}
|
|
251
262
|
}
|
|
252
263
|
|
|
253
|
-
// private fun remoteIncomingCallNotif() {
|
|
254
|
-
// CallService.removeIncomingCall(
|
|
255
|
-
// context,
|
|
256
|
-
// StreamCallId.fromCallCid(call.cid),
|
|
257
|
-
// StreamVideo.instance().state.callConfigRegistry.get(call.type),
|
|
258
|
-
// )
|
|
259
|
-
// }
|
|
260
|
-
|
|
261
264
|
private fun setupViews() {
|
|
262
265
|
val context = context
|
|
263
266
|
val parent = bridge?.webView?.parent as? ViewGroup ?: return
|
|
@@ -468,16 +471,17 @@ public class StreamCallPlugin : Plugin() {
|
|
|
468
471
|
)
|
|
469
472
|
|
|
470
473
|
val notificationConfig = NotificationConfig(
|
|
471
|
-
pushDeviceGenerators = listOf(
|
|
474
|
+
pushDeviceGenerators = listOf(
|
|
475
|
+
FirebasePushDeviceGenerator(
|
|
472
476
|
providerName = "firebase",
|
|
473
477
|
context = contextToUse
|
|
474
|
-
)
|
|
478
|
+
)
|
|
479
|
+
),
|
|
475
480
|
requestPermissionOnAppLaunch = { true },
|
|
476
481
|
notificationHandler = notificationHandler,
|
|
477
482
|
)
|
|
478
483
|
|
|
479
|
-
val soundsConfig =
|
|
480
|
-
soundsConfig.incomingCallSoundUri
|
|
484
|
+
val soundsConfig = incomingOnlyRingingConfig()
|
|
481
485
|
// Initialize StreamVideo client
|
|
482
486
|
streamVideoClient = StreamVideoBuilder(
|
|
483
487
|
context = contextToUse,
|
|
@@ -562,61 +566,37 @@ public class StreamCallPlugin : Plugin() {
|
|
|
562
566
|
android.util.Log.v("StreamCallPlugin", "Received an event ${event.getEventType()} $event")
|
|
563
567
|
when (event) {
|
|
564
568
|
// Handle CallCreatedEvent differently - only log it but don't try to access members yet
|
|
565
|
-
is
|
|
566
|
-
val callCid = event.
|
|
569
|
+
is CallCreatedEvent -> {
|
|
570
|
+
val callCid = event.callCid
|
|
567
571
|
android.util.Log.d("StreamCallPlugin", "Call created: $callCid")
|
|
568
572
|
|
|
569
573
|
// let's get the members
|
|
570
|
-
val callParticipants = event.members.filter{ it.user.id != this@StreamCallPlugin.streamVideoClient?.userId }
|
|
574
|
+
val callParticipants = event.members.filter{ it.user.id != this@StreamCallPlugin.streamVideoClient?.userId }.map { it.user.id }
|
|
571
575
|
android.util.Log.d("StreamCallPlugin", "Call created for $callCid with ${callParticipants.size} participants")
|
|
572
576
|
|
|
573
577
|
// Start tracking this call now that we have the member list
|
|
574
578
|
startCallTimeoutMonitor(callCid, callParticipants)
|
|
575
579
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}
|
|
580
|
-
notifyListeners("callEvent", data)
|
|
580
|
+
// Use direction from event if available
|
|
581
|
+
val callType = callCid.split(":").firstOrNull() ?: "default"
|
|
582
|
+
updateCallStatusAndNotify(callCid, "created")
|
|
581
583
|
}
|
|
582
584
|
// Add handler for CallSessionStartedEvent which contains participant information
|
|
583
|
-
is
|
|
584
|
-
val callCid = event.
|
|
585
|
-
|
|
586
|
-
val data = JSObject().apply {
|
|
587
|
-
put("callId", callCid)
|
|
588
|
-
put("state", "session_started")
|
|
589
|
-
}
|
|
590
|
-
notifyListeners("callEvent", data)
|
|
585
|
+
is CallSessionStartedEvent -> {
|
|
586
|
+
val callCid = event.callCid
|
|
587
|
+
updateCallStatusAndNotify(callCid, "session_started")
|
|
591
588
|
}
|
|
592
589
|
|
|
593
590
|
is CallRejectedEvent -> {
|
|
594
591
|
val userId = event.user.id
|
|
595
|
-
val callCid = event.
|
|
592
|
+
val callCid = event.callCid
|
|
596
593
|
|
|
597
594
|
// Update call state
|
|
598
595
|
callStates[callCid]?.let { callState ->
|
|
599
596
|
callState.participantResponses[userId] = "rejected"
|
|
600
597
|
}
|
|
601
598
|
|
|
602
|
-
|
|
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
|
-
|
|
614
|
-
val data = JSObject().apply {
|
|
615
|
-
put("callId", event.call.cid)
|
|
616
|
-
put("state", "rejected")
|
|
617
|
-
put("userId", userId)
|
|
618
|
-
}
|
|
619
|
-
notifyListeners("callEvent", data)
|
|
599
|
+
updateCallStatusAndNotify(callCid, "rejected", userId)
|
|
620
600
|
|
|
621
601
|
// Check if all participants have responded
|
|
622
602
|
checkAllParticipantsResponded(callCid)
|
|
@@ -624,7 +604,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
624
604
|
|
|
625
605
|
is CallMissedEvent -> {
|
|
626
606
|
val userId = event.user.id
|
|
627
|
-
val callCid = event.
|
|
607
|
+
val callCid = event.callCid
|
|
628
608
|
|
|
629
609
|
// Update call state
|
|
630
610
|
callStates[callCid]?.let { callState ->
|
|
@@ -638,12 +618,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
638
618
|
moveAllActivitiesToBackgroundOrKill(context)
|
|
639
619
|
}
|
|
640
620
|
|
|
641
|
-
|
|
642
|
-
put("callId", callCid)
|
|
643
|
-
put("state", "missed")
|
|
644
|
-
put("userId", userId)
|
|
645
|
-
}
|
|
646
|
-
notifyListeners("callEvent", data)
|
|
621
|
+
updateCallStatusAndNotify(callCid, "missed", userId)
|
|
647
622
|
|
|
648
623
|
// Check if all participants have responded
|
|
649
624
|
checkAllParticipantsResponded(callCid)
|
|
@@ -651,7 +626,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
651
626
|
|
|
652
627
|
is CallAcceptedEvent -> {
|
|
653
628
|
val userId = event.user.id
|
|
654
|
-
val callCid = event.
|
|
629
|
+
val callCid = event.callCid
|
|
655
630
|
|
|
656
631
|
// Update call state
|
|
657
632
|
callStates[callCid]?.let { callState ->
|
|
@@ -663,48 +638,34 @@ public class StreamCallPlugin : Plugin() {
|
|
|
663
638
|
callState.timer = null
|
|
664
639
|
}
|
|
665
640
|
|
|
666
|
-
|
|
667
|
-
put("callId", callCid)
|
|
668
|
-
put("state", "accepted")
|
|
669
|
-
put("userId", userId)
|
|
670
|
-
}
|
|
671
|
-
notifyListeners("callEvent", data)
|
|
641
|
+
updateCallStatusAndNotify(callCid, "accepted", userId)
|
|
672
642
|
}
|
|
673
643
|
|
|
674
644
|
is CallEndedEvent -> {
|
|
675
645
|
runOnMainThread {
|
|
676
|
-
android.util.Log.d("StreamCallPlugin", "Setting overlay invisible due to CallEndedEvent for call ${event.
|
|
646
|
+
android.util.Log.d("StreamCallPlugin", "Setting overlay invisible due to CallEndedEvent for call ${event.callCid}")
|
|
677
647
|
// Clean up call resources
|
|
678
|
-
val callCid = event.
|
|
648
|
+
val callCid = event.callCid
|
|
679
649
|
cleanupCall(callCid)
|
|
680
650
|
}
|
|
681
|
-
|
|
682
|
-
put("callId", event.call.cid)
|
|
683
|
-
put("state", "left")
|
|
684
|
-
}
|
|
685
|
-
notifyListeners("callEvent", data)
|
|
651
|
+
updateCallStatusAndNotify(event.callCid, "left")
|
|
686
652
|
}
|
|
687
653
|
|
|
688
654
|
is CallSessionEndedEvent -> {
|
|
689
655
|
runOnMainThread {
|
|
690
|
-
android.util.Log.d("StreamCallPlugin", "Setting overlay invisible due to CallSessionEndedEvent for call ${event.call.
|
|
656
|
+
android.util.Log.d("StreamCallPlugin", "Setting overlay invisible due to CallSessionEndedEvent for call ${event.callCid}. Test session: ${event.call.session?.endedAt}")
|
|
691
657
|
// Clean up call resources
|
|
692
|
-
val callCid = event.
|
|
658
|
+
val callCid = event.callCid
|
|
693
659
|
cleanupCall(callCid)
|
|
694
660
|
}
|
|
695
|
-
|
|
696
|
-
put("callId", event.call.cid)
|
|
697
|
-
put("state", "left")
|
|
698
|
-
}
|
|
699
|
-
notifyListeners("callEvent", data)
|
|
661
|
+
updateCallStatusAndNotify(event.callCid, "left")
|
|
700
662
|
}
|
|
701
663
|
|
|
702
664
|
else -> {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
notifyListeners("callEvent", data)
|
|
665
|
+
updateCallStatusAndNotify(
|
|
666
|
+
streamVideoClient?.state?.activeCall?.value?.cid ?: "",
|
|
667
|
+
event.getEventType()
|
|
668
|
+
)
|
|
708
669
|
}
|
|
709
670
|
}
|
|
710
671
|
}
|
|
@@ -721,19 +682,11 @@ public class StreamCallPlugin : Plugin() {
|
|
|
721
682
|
android.util.Log.d("StreamCallPlugin", "- All participants: ${state.participants}")
|
|
722
683
|
android.util.Log.d("StreamCallPlugin", "- Remote participants: ${state.remoteParticipants}")
|
|
723
684
|
|
|
724
|
-
// Notify that a call has started
|
|
725
|
-
|
|
726
|
-
put("callId", call.cid)
|
|
727
|
-
put("state", "joined")
|
|
728
|
-
}
|
|
729
|
-
notifyListeners("callEvent", data)
|
|
685
|
+
// Notify that a call has started using our helper
|
|
686
|
+
updateCallStatusAndNotify(call.cid, "joined")
|
|
730
687
|
} ?: run {
|
|
731
|
-
// Notify that call has ended
|
|
732
|
-
|
|
733
|
-
put("callId", "")
|
|
734
|
-
put("state", "left")
|
|
735
|
-
}
|
|
736
|
-
notifyListeners("callEvent", data)
|
|
688
|
+
// Notify that call has ended using our helper
|
|
689
|
+
updateCallStatusAndNotify("", "left")
|
|
737
690
|
}
|
|
738
691
|
}
|
|
739
692
|
}
|
|
@@ -807,12 +760,8 @@ public class StreamCallPlugin : Plugin() {
|
|
|
807
760
|
// Join the call without affecting others
|
|
808
761
|
call.accept()
|
|
809
762
|
|
|
810
|
-
// Notify that call has started
|
|
811
|
-
|
|
812
|
-
put("callId", call.id)
|
|
813
|
-
put("state", "joined")
|
|
814
|
-
}
|
|
815
|
-
notifyListeners("callEvent", data)
|
|
763
|
+
// Notify that call has started using helper
|
|
764
|
+
updateCallStatusAndNotify(call.id, "joined")
|
|
816
765
|
|
|
817
766
|
// Show overlay view with the active call
|
|
818
767
|
runOnMainThread {
|
|
@@ -935,7 +884,6 @@ public class StreamCallPlugin : Plugin() {
|
|
|
935
884
|
val callId = call.id
|
|
936
885
|
android.util.Log.d("StreamCallPlugin", "Attempting to end call $callId")
|
|
937
886
|
call.leave()
|
|
938
|
-
call.reject(reason = RejectReason.Cancel)
|
|
939
887
|
|
|
940
888
|
// Capture context from the overlayView
|
|
941
889
|
val currentContext = overlayView?.context ?: this.savedContext
|
|
@@ -988,12 +936,8 @@ public class StreamCallPlugin : Plugin() {
|
|
|
988
936
|
incomingCallView?.isVisible = false
|
|
989
937
|
}
|
|
990
938
|
|
|
991
|
-
// Notify that call has ended
|
|
992
|
-
|
|
993
|
-
put("callId", callId)
|
|
994
|
-
put("state", "left")
|
|
995
|
-
}
|
|
996
|
-
notifyListeners("callEvent", data)
|
|
939
|
+
// Notify that call has ended using helper
|
|
940
|
+
updateCallStatusAndNotify(callId, "left")
|
|
997
941
|
}
|
|
998
942
|
|
|
999
943
|
@OptIn(DelicateCoroutinesApi::class)
|
|
@@ -1079,7 +1023,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1079
1023
|
val callType = call.getString("type") ?: "default"
|
|
1080
1024
|
val shouldRing = call.getBoolean("ring") ?: true
|
|
1081
1025
|
val callId = java.util.UUID.randomUUID().toString()
|
|
1082
|
-
val
|
|
1026
|
+
val team = call.getString("team");
|
|
1083
1027
|
|
|
1084
1028
|
android.util.Log.d("StreamCallPlugin", "Creating call:")
|
|
1085
1029
|
android.util.Log.d("StreamCallPlugin", "- Call ID: $callId")
|
|
@@ -1098,15 +1042,23 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1098
1042
|
|
|
1099
1043
|
android.util.Log.d("StreamCallPlugin", "Creating call with members...")
|
|
1100
1044
|
// Create the call with all members
|
|
1101
|
-
streamCall?.create(
|
|
1045
|
+
val createResult = streamCall?.create(
|
|
1102
1046
|
memberIds = userIds + selfUserId,
|
|
1103
1047
|
custom = emptyMap(),
|
|
1104
|
-
ring = shouldRing
|
|
1048
|
+
ring = shouldRing,
|
|
1049
|
+
team = team,
|
|
1105
1050
|
)
|
|
1051
|
+
|
|
1052
|
+
if (createResult?.isFailure == true) {
|
|
1053
|
+
throw (createResult.errorOrNull() ?: RuntimeException("Unknown error creating call")) as Throwable
|
|
1054
|
+
}
|
|
1106
1055
|
|
|
1107
1056
|
android.util.Log.d("StreamCallPlugin", "Setting overlay visible for outgoing call $callId")
|
|
1108
1057
|
// Show overlay view
|
|
1109
1058
|
activity?.runOnUiThread {
|
|
1059
|
+
streamCall?.microphone?.setEnabled(true)
|
|
1060
|
+
streamCall?.camera?.setEnabled(true)
|
|
1061
|
+
|
|
1110
1062
|
overlayView?.setContent {
|
|
1111
1063
|
CallOverlayView(
|
|
1112
1064
|
context = context,
|
|
@@ -1132,7 +1084,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1132
1084
|
}
|
|
1133
1085
|
|
|
1134
1086
|
private fun startCallTimeoutMonitor(callCid: String, memberIds: List<String>) {
|
|
1135
|
-
val callState =
|
|
1087
|
+
val callState = LocalCallState(members = memberIds)
|
|
1136
1088
|
|
|
1137
1089
|
val handler = Handler(Looper.getMainLooper())
|
|
1138
1090
|
val timeoutRunnable = object : Runnable {
|
|
@@ -1172,12 +1124,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1172
1124
|
if (memberId !in callState.participantResponses) {
|
|
1173
1125
|
callState.participantResponses[memberId] = "missed"
|
|
1174
1126
|
|
|
1175
|
-
|
|
1176
|
-
put("callId", callCid)
|
|
1177
|
-
put("state", "missed")
|
|
1178
|
-
put("userId", memberId)
|
|
1179
|
-
}
|
|
1180
|
-
notifyListeners("callEvent", data)
|
|
1127
|
+
updateCallStatusAndNotify(callCid, "missed", memberId)
|
|
1181
1128
|
}
|
|
1182
1129
|
}
|
|
1183
1130
|
|
|
@@ -1195,13 +1142,8 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1195
1142
|
// Clean up state - we don't need to do this in endCallRaw because we already did it here
|
|
1196
1143
|
callStates.remove(callCid)
|
|
1197
1144
|
|
|
1198
|
-
// Notify that call has ended
|
|
1199
|
-
|
|
1200
|
-
put("callId", callCid)
|
|
1201
|
-
put("state", "ended")
|
|
1202
|
-
put("reason", "timeout")
|
|
1203
|
-
}
|
|
1204
|
-
notifyListeners("callEvent", data)
|
|
1145
|
+
// Notify that call has ended using helper
|
|
1146
|
+
updateCallStatusAndNotify(callCid, "ended", null, "timeout")
|
|
1205
1147
|
} catch (e: Exception) {
|
|
1206
1148
|
android.util.Log.e("StreamCallPlugin", "Error ending timed out call", e)
|
|
1207
1149
|
}
|
|
@@ -1271,13 +1213,8 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1271
1213
|
// Clean up state - we don't need to do this in endCallRaw because we already did it here
|
|
1272
1214
|
callStates.remove(callCid)
|
|
1273
1215
|
|
|
1274
|
-
// Notify that call has ended
|
|
1275
|
-
|
|
1276
|
-
put("callId", callCid)
|
|
1277
|
-
put("state", "ended")
|
|
1278
|
-
put("reason", "all_rejected_or_missed")
|
|
1279
|
-
}
|
|
1280
|
-
notifyListeners("callEvent", data)
|
|
1216
|
+
// Notify that call has ended using helper
|
|
1217
|
+
updateCallStatusAndNotify(callCid, "ended", null, "all_rejected_or_missed")
|
|
1281
1218
|
} catch (e: Exception) {
|
|
1282
1219
|
android.util.Log.e("StreamCallPlugin", "Error ending call after all rejected/missed", e)
|
|
1283
1220
|
}
|
|
@@ -1289,68 +1226,68 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1289
1226
|
|
|
1290
1227
|
private suspend fun magicDeviceDelete(streamVideoClient: StreamVideo) {
|
|
1291
1228
|
try {
|
|
1292
|
-
android.util.Log.d("StreamCallPlugin", "Starting magicDeviceDelete
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
android.util.Log.e("StreamCallPlugin", "streamNotificationManager is null")
|
|
1302
|
-
return
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
android.util.Log.d("StreamCallPlugin", "Successfully accessed streamNotificationManager")
|
|
1306
|
-
|
|
1307
|
-
// Get deviceTokenStorage from notification manager
|
|
1308
|
-
val notificationManagerClass = notificationManager.javaClass
|
|
1309
|
-
val deviceTokenStorageField = notificationManagerClass.getDeclaredField("deviceTokenStorage")
|
|
1310
|
-
deviceTokenStorageField.isAccessible = true
|
|
1311
|
-
val deviceTokenStorage = deviceTokenStorageField.get(notificationManager)
|
|
1312
|
-
|
|
1313
|
-
if (deviceTokenStorage == null) {
|
|
1314
|
-
android.util.Log.e("StreamCallPlugin", "deviceTokenStorage is null")
|
|
1315
|
-
return
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
android.util.Log.d("StreamCallPlugin", "Successfully accessed deviceTokenStorage")
|
|
1319
|
-
|
|
1320
|
-
// Access the DeviceTokenStorage object dynamically without hardcoding class
|
|
1321
|
-
val deviceTokenStorageClass = deviceTokenStorage.javaClass
|
|
1322
|
-
|
|
1323
|
-
// Get the userDevice Flow from deviceTokenStorage
|
|
1324
|
-
val userDeviceField = deviceTokenStorageClass.getDeclaredField("userDevice")
|
|
1325
|
-
userDeviceField.isAccessible = true
|
|
1326
|
-
val userDeviceFlow = userDeviceField.get(deviceTokenStorage)
|
|
1327
|
-
|
|
1328
|
-
if (userDeviceFlow == null) {
|
|
1329
|
-
android.util.Log.e("StreamCallPlugin", "userDevice Flow is null")
|
|
1330
|
-
return
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
android.util.Log.d("StreamCallPlugin", "Successfully accessed userDevice Flow: $userDeviceFlow")
|
|
1229
|
+
android.util.Log.d("StreamCallPlugin", "Starting magicDeviceDelete operation")
|
|
1230
|
+
|
|
1231
|
+
FirebaseMessaging.getInstance().token.await()?.let {
|
|
1232
|
+
android.util.Log.d("StreamCallPlugin", "Found firebase token")
|
|
1233
|
+
val device = Device(
|
|
1234
|
+
id = it,
|
|
1235
|
+
pushProvider = PushProvider.FIREBASE.key,
|
|
1236
|
+
pushProviderName = "firebase",
|
|
1237
|
+
)
|
|
1334
1238
|
|
|
1335
|
-
|
|
1336
|
-
try {
|
|
1337
|
-
castedUserDeviceFlow.first {
|
|
1338
|
-
if (it == null) {
|
|
1339
|
-
android.util.Log.d("StreamCallPlugin", "Device is null. Nothing to remove")
|
|
1340
|
-
return@first true;
|
|
1341
|
-
}
|
|
1342
|
-
streamVideoClient.deleteDevice(it)
|
|
1343
|
-
return@first true;
|
|
1344
|
-
}
|
|
1345
|
-
} catch (e: Throwable) {
|
|
1346
|
-
android.util.Log.e("StreamCallPlugin", "Cannot collect flow in magicDeviceDelete", e)
|
|
1239
|
+
streamVideoClient.deleteDevice(device)
|
|
1347
1240
|
}
|
|
1348
1241
|
} catch (e: Exception) {
|
|
1349
1242
|
android.util.Log.e("StreamCallPlugin", "Error in magicDeviceDelete", e)
|
|
1350
1243
|
}
|
|
1351
1244
|
}
|
|
1352
1245
|
|
|
1353
|
-
|
|
1246
|
+
@PluginMethod
|
|
1247
|
+
fun getCallStatus(call: PluginCall) {
|
|
1248
|
+
// If not in a call, reject
|
|
1249
|
+
if (currentCallId.isEmpty() || currentCallState == "left") {
|
|
1250
|
+
call.reject("Not in a call")
|
|
1251
|
+
return
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
val result = JSObject()
|
|
1255
|
+
result.put("callId", currentCallId)
|
|
1256
|
+
result.put("state", currentCallState)
|
|
1257
|
+
|
|
1258
|
+
// No additional fields to ensure compatibility with CallEvent interface
|
|
1259
|
+
|
|
1260
|
+
call.resolve(result)
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
// Helper method to update call status and notify listeners
|
|
1264
|
+
private fun updateCallStatusAndNotify(callId: String, state: String, userId: String? = null, reason: String? = null) {
|
|
1265
|
+
// Update stored call info
|
|
1266
|
+
currentCallId = callId
|
|
1267
|
+
currentCallState = state
|
|
1268
|
+
|
|
1269
|
+
// Get call type from call ID if available
|
|
1270
|
+
if (callId.contains(":")) {
|
|
1271
|
+
currentCallType = callId.split(":").firstOrNull() ?: ""
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
// Create data object with only the fields in the CallEvent interface
|
|
1275
|
+
val data = JSObject().apply {
|
|
1276
|
+
put("callId", callId)
|
|
1277
|
+
put("state", state)
|
|
1278
|
+
userId?.let {
|
|
1279
|
+
put("userId", it)
|
|
1280
|
+
}
|
|
1281
|
+
reason?.let {
|
|
1282
|
+
put("reason", it)
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// Notify listeners
|
|
1287
|
+
notifyListeners("callEvent", data)
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
data class LocalCallState(
|
|
1354
1291
|
val members: List<String>,
|
|
1355
1292
|
val participantResponses: MutableMap<String, String> = mutableMapOf(),
|
|
1356
1293
|
val createdAt: Long = System.currentTimeMillis(),
|