@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.
- package/Package.swift +31 -0
- package/README.md +340 -0
- package/StreamCall.podspec +19 -0
- package/android/build.gradle +74 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/ee/forgr/capacitor/streamcall/CallOverlayView.kt +281 -0
- package/android/src/main/java/ee/forgr/capacitor/streamcall/CustomNotificationHandler.kt +142 -0
- package/android/src/main/java/ee/forgr/capacitor/streamcall/IncomingCallView.kt +147 -0
- package/android/src/main/java/ee/forgr/capacitor/streamcall/RingtonePlayer.kt +164 -0
- package/android/src/main/java/ee/forgr/capacitor/streamcall/StreamCallPlugin.kt +1014 -0
- package/android/src/main/java/ee/forgr/capacitor/streamcall/TouchInterceptWrapper.kt +31 -0
- package/android/src/main/java/ee/forgr/capacitor/streamcall/UserRepository.kt +111 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/values/strings.xml +7 -0
- package/dist/docs.json +533 -0
- package/dist/esm/definitions.d.ts +169 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +32 -0
- package/dist/esm/web.js +323 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +337 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +339 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/StreamCallPlugin/CallOverlayView.swift +147 -0
- package/ios/Sources/StreamCallPlugin/CustomCallParticipantImageView.swift +60 -0
- package/ios/Sources/StreamCallPlugin/CustomCallView.swift +257 -0
- package/ios/Sources/StreamCallPlugin/CustomVideoParticipantsView.swift +107 -0
- package/ios/Sources/StreamCallPlugin/ParticipantsView.swift +206 -0
- package/ios/Sources/StreamCallPlugin/StreamCallPlugin.swift +722 -0
- package/ios/Sources/StreamCallPlugin/TouchInterceptView.swift +177 -0
- package/ios/Sources/StreamCallPlugin/UserRepository.swift +96 -0
- package/ios/Sources/StreamCallPlugin/WebviewNavigationDelegate.swift +68 -0
- package/ios/Tests/StreamCallPluginTests/StreamCallPluginTests.swift +15 -0
- 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
|
+
}
|