@capgo/capacitor-stream-call 0.0.2

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.
Files changed (39) hide show
  1. package/Package.swift +31 -0
  2. package/README.md +340 -0
  3. package/StreamCall.podspec +19 -0
  4. package/android/build.gradle +74 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/ee/forgr/capacitor/streamcall/CallOverlayView.kt +281 -0
  7. package/android/src/main/java/ee/forgr/capacitor/streamcall/CustomNotificationHandler.kt +142 -0
  8. package/android/src/main/java/ee/forgr/capacitor/streamcall/IncomingCallView.kt +147 -0
  9. package/android/src/main/java/ee/forgr/capacitor/streamcall/RingtonePlayer.kt +164 -0
  10. package/android/src/main/java/ee/forgr/capacitor/streamcall/StreamCallPlugin.kt +1014 -0
  11. package/android/src/main/java/ee/forgr/capacitor/streamcall/TouchInterceptWrapper.kt +31 -0
  12. package/android/src/main/java/ee/forgr/capacitor/streamcall/UserRepository.kt +111 -0
  13. package/android/src/main/res/.gitkeep +0 -0
  14. package/android/src/main/res/values/strings.xml +7 -0
  15. package/dist/docs.json +533 -0
  16. package/dist/esm/definitions.d.ts +169 -0
  17. package/dist/esm/definitions.js +2 -0
  18. package/dist/esm/definitions.js.map +1 -0
  19. package/dist/esm/index.d.ts +4 -0
  20. package/dist/esm/index.js +7 -0
  21. package/dist/esm/index.js.map +1 -0
  22. package/dist/esm/web.d.ts +32 -0
  23. package/dist/esm/web.js +323 -0
  24. package/dist/esm/web.js.map +1 -0
  25. package/dist/plugin.cjs.js +337 -0
  26. package/dist/plugin.cjs.js.map +1 -0
  27. package/dist/plugin.js +339 -0
  28. package/dist/plugin.js.map +1 -0
  29. package/ios/Sources/StreamCallPlugin/CallOverlayView.swift +147 -0
  30. package/ios/Sources/StreamCallPlugin/CustomCallParticipantImageView.swift +60 -0
  31. package/ios/Sources/StreamCallPlugin/CustomCallView.swift +257 -0
  32. package/ios/Sources/StreamCallPlugin/CustomVideoParticipantsView.swift +107 -0
  33. package/ios/Sources/StreamCallPlugin/ParticipantsView.swift +206 -0
  34. package/ios/Sources/StreamCallPlugin/StreamCallPlugin.swift +722 -0
  35. package/ios/Sources/StreamCallPlugin/TouchInterceptView.swift +177 -0
  36. package/ios/Sources/StreamCallPlugin/UserRepository.swift +96 -0
  37. package/ios/Sources/StreamCallPlugin/WebviewNavigationDelegate.swift +68 -0
  38. package/ios/Tests/StreamCallPluginTests/StreamCallPluginTests.swift +15 -0
  39. package/package.json +96 -0
@@ -0,0 +1,164 @@
1
+ package ee.forgr.capacitor.streamcall
2
+
3
+ import android.app.Application
4
+ import android.app.Notification
5
+ import android.app.NotificationManager
6
+ import android.content.Context
7
+ import android.media.AudioAttributes
8
+ import android.media.MediaPlayer
9
+ import android.media.RingtoneManager
10
+ import android.os.Build
11
+ import android.os.Handler
12
+ import android.os.Looper
13
+ import android.util.Log
14
+ import io.getstream.video.android.core.notifications.NotificationHandler
15
+
16
+ class RingtonePlayer(
17
+ private val application: Application,
18
+ private val cancelIncomingCallService: () -> Unit = { }
19
+ ) {
20
+ companion object {
21
+ private const val DEFAULT_RINGTONE_DURATION = 30000L // 30 seconds in milliseconds
22
+ }
23
+
24
+ private var mediaPlayer: MediaPlayer? = null
25
+ private val handler = Handler(Looper.getMainLooper())
26
+ private var stopRingtoneRunnable: Runnable? = null
27
+ private var isPaused = false
28
+ private var isStopped = true
29
+
30
+ private fun isOurNotification(notification: android.service.notification.StatusBarNotification): Boolean {
31
+ return notification.id == NotificationHandler.INCOMING_CALL_NOTIFICATION_ID
32
+ }
33
+
34
+ fun pauseRinging() {
35
+ Log.d("RingtonePlayer", "Pause ringing")
36
+ try {
37
+ if (!isStopped) {
38
+ mediaPlayer?.pause()
39
+ isPaused = true
40
+ }
41
+ } catch (e: Exception) {
42
+ Log.e("RingtonePlayer", "Error pausing ringtone: ${e.message}")
43
+ }
44
+ }
45
+
46
+ fun resumeRinging() {
47
+ Log.d("RingtonePlayer", "Resume ringing")
48
+ try {
49
+ if (!isStopped && isPaused) {
50
+ mediaPlayer?.start()
51
+ isPaused = false
52
+ }
53
+ } catch (e: Exception) {
54
+ Log.e("RingtonePlayer", "Error resuming ringtone: ${e.message}")
55
+ }
56
+ }
57
+
58
+ fun isPaused(): Boolean {
59
+ return isPaused
60
+ }
61
+
62
+ fun startRinging() {
63
+ Log.d("RingtonePlayer", "Start ringing")
64
+ try {
65
+ isStopped = false
66
+ isPaused = false
67
+ if (mediaPlayer == null) {
68
+ val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
69
+ mediaPlayer = MediaPlayer().apply {
70
+ setDataSource(application, uri)
71
+ isLooping = true
72
+ setAudioAttributes(
73
+ AudioAttributes.Builder()
74
+ .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
75
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
76
+ .build()
77
+ )
78
+ prepare()
79
+ }
80
+ }
81
+
82
+ val notificationManager = application.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
83
+ val notifs = notificationManager.activeNotifications.toList()
84
+ var notificationTime = 0L
85
+
86
+ for (notification in notifs) {
87
+ // First check if it's our notification
88
+ val isOurs = isOurNotification(notification)
89
+
90
+ // Only proceed with ringtone if it's our notification
91
+ if (!isOurs) {
92
+ Log.d("RingtonePlayer", "Skipping notification as it's not our incoming call notification")
93
+ continue
94
+ }
95
+
96
+ // Cancel our notification
97
+ try {
98
+ Log.d("RingtonePlayer", "Canceling notification/service with id: ${notification.id}")
99
+ this.cancelIncomingCallService()
100
+ } catch (e: Exception) {
101
+ Log.e("RingtonePlayer", "Error cancelling notification: ${e.message}")
102
+ }
103
+ notificationTime = notification.postTime
104
+ }
105
+
106
+ if (notificationTime > 0) {
107
+ val currentTime = System.currentTimeMillis()
108
+ val elapsedTime = currentTime - notificationTime
109
+
110
+ // Only start playing if we're within the ringtone duration
111
+ if (elapsedTime < DEFAULT_RINGTONE_DURATION) {
112
+ // Get the ringtone duration
113
+ val ringtoneDuration = mediaPlayer?.duration?.toLong() ?: DEFAULT_RINGTONE_DURATION
114
+
115
+ // Calculate the position to seek to
116
+ val seekPosition = (elapsedTime % ringtoneDuration).toInt()
117
+ Log.d("RingtonePlayer", "Seeking to position: $seekPosition ms in ringtone")
118
+
119
+ mediaPlayer?.seekTo(seekPosition)
120
+ mediaPlayer?.start()
121
+
122
+ // Schedule stop at the remaining duration
123
+ val remainingDuration = DEFAULT_RINGTONE_DURATION - elapsedTime
124
+ stopRingtoneRunnable = Runnable { stopRinging() }
125
+ handler.postDelayed(stopRingtoneRunnable!!, remainingDuration)
126
+
127
+ Log.d("RingtonePlayer", "Starting ringtone with offset: $elapsedTime ms, will play for $remainingDuration ms")
128
+ } else {
129
+ Log.d("RingtonePlayer", "Not starting ringtone as elapsed time ($elapsedTime ms) exceeds duration")
130
+ }
131
+ } else {
132
+ // If no notification time found, just play normally
133
+ mediaPlayer?.start()
134
+
135
+ // Schedule stop at the default duration
136
+ stopRingtoneRunnable = Runnable { stopRinging() }
137
+ handler.postDelayed(stopRingtoneRunnable!!, DEFAULT_RINGTONE_DURATION)
138
+
139
+ Log.d("RingtonePlayer", "Starting ringtone with default duration")
140
+ }
141
+ } catch (e: Exception) {
142
+ Log.e("RingtonePlayer", "Error playing ringtone: ${e.message}")
143
+ }
144
+ }
145
+
146
+ fun stopRinging() {
147
+ Log.d("RingtonePlayer", "Stop ringing")
148
+ try {
149
+ isStopped = true
150
+ isPaused = false
151
+ stopRingtoneRunnable?.let { handler.removeCallbacks(it) }
152
+ stopRingtoneRunnable = null
153
+
154
+ mediaPlayer?.stop()
155
+ mediaPlayer?.reset()
156
+ mediaPlayer?.release()
157
+ mediaPlayer = null
158
+ } catch (e: Exception) {
159
+ Log.e("RingtonePlayer", "Error stopping ringtone: ${e.message}")
160
+ }
161
+ }
162
+
163
+
164
+ }