@capgo/capacitor-stream-call 0.0.82 → 0.0.83
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/android/src/main/java/ee/forgr/capacitor/streamcall/CustomNotificationHandler.kt +2 -2
- package/android/src/main/java/ee/forgr/capacitor/streamcall/StreamCallFragment.kt +8 -36
- package/android/src/main/java/ee/forgr/capacitor/streamcall/StreamCallPlugin.kt +290 -308
- package/android/src/main/java/ee/forgr/capacitor/streamcall/TouchInterceptWrapper.kt +5 -3
- package/android/src/main/java/ee/forgr/capacitor/streamcall/UserRepository.kt +4 -5
- package/ios/Sources/StreamCallPlugin/StreamCallPlugin.swift +0 -4
- package/package.json +1 -1
- package/android/src/main/java/ee/forgr/capacitor/streamcall/RingtonePlayer.kt +0 -162
|
@@ -2,6 +2,8 @@ import android.view.MotionEvent
|
|
|
2
2
|
import android.view.ViewGroup
|
|
3
3
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
4
4
|
import android.util.Log
|
|
5
|
+
import androidx.core.view.isNotEmpty
|
|
6
|
+
import androidx.core.view.isVisible
|
|
5
7
|
|
|
6
8
|
class TouchInterceptWrapper(private val originalViewGroup: ViewGroup) : CoordinatorLayout(
|
|
7
9
|
originalViewGroup.context
|
|
@@ -9,7 +11,7 @@ class TouchInterceptWrapper(private val originalViewGroup: ViewGroup) : Coordina
|
|
|
9
11
|
init {
|
|
10
12
|
// Copy layout parameters and children
|
|
11
13
|
layoutParams = originalViewGroup.layoutParams
|
|
12
|
-
while (originalViewGroup.
|
|
14
|
+
while (originalViewGroup.isNotEmpty()) {
|
|
13
15
|
val child = originalViewGroup.getChildAt(0)
|
|
14
16
|
originalViewGroup.removeViewAt(0)
|
|
15
17
|
addView(child)
|
|
@@ -23,8 +25,8 @@ class TouchInterceptWrapper(private val originalViewGroup: ViewGroup) : Coordina
|
|
|
23
25
|
// Traverse children from top (highest z) to bottom
|
|
24
26
|
for (i in childCount - 1 downTo 0) {
|
|
25
27
|
val child = getChildAt(i)
|
|
26
|
-
Log.d("TouchInterceptWrapper", "Checking child $i: ${child::class.java.simpleName}, visibility: ${child.
|
|
27
|
-
if (child.
|
|
28
|
+
Log.d("TouchInterceptWrapper", "Checking child $i: ${child::class.java.simpleName}, visibility: ${child.isVisible}")
|
|
29
|
+
if (child.isVisible) {
|
|
28
30
|
val copy = MotionEvent.obtain(ev)
|
|
29
31
|
// It's important to transform event coordinates to the child's coordinate system
|
|
30
32
|
copy.offsetLocation(-child.left.toFloat(), -child.top.toFloat())
|
|
@@ -5,6 +5,7 @@ import android.content.SharedPreferences
|
|
|
5
5
|
import android.util.ArrayMap
|
|
6
6
|
import io.getstream.video.android.model.User
|
|
7
7
|
import org.json.JSONObject
|
|
8
|
+
import androidx.core.content.edit
|
|
8
9
|
|
|
9
10
|
data class UserCredentials(
|
|
10
11
|
val user: User,
|
|
@@ -65,15 +66,14 @@ class SecureUserRepository private constructor(context: Context) : UserRepositor
|
|
|
65
66
|
put("custom", customJson)
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
sharedPreferences.edit {
|
|
69
70
|
putString(KEY_USER, userJson.toString())
|
|
70
71
|
putString(KEY_TOKEN, user.tokenValue)
|
|
71
|
-
apply()
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
override fun save(token: String) {
|
|
76
|
-
sharedPreferences.edit
|
|
76
|
+
sharedPreferences.edit { putString(KEY_TOKEN, token) }
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
override fun loadCurrentUser(): UserCredentials? {
|
|
@@ -102,10 +102,9 @@ class SecureUserRepository private constructor(context: Context) : UserRepositor
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
override fun removeCurrentUser() {
|
|
105
|
-
|
|
105
|
+
sharedPreferences.edit {
|
|
106
106
|
remove(KEY_USER)
|
|
107
107
|
remove(KEY_TOKEN)
|
|
108
|
-
apply()
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
}
|
|
@@ -1043,10 +1043,6 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1043
1043
|
return UserDefaults.standard.string(forKey: dynamicApiKeyKey)
|
|
1044
1044
|
}
|
|
1045
1045
|
|
|
1046
|
-
func clearDynamicApiKey() {
|
|
1047
|
-
UserDefaults.standard.removeObject(forKey: dynamicApiKeyKey)
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
1046
|
func getEffectiveApiKey() -> String? {
|
|
1051
1047
|
// A) Check if the key exists in UserDefaults
|
|
1052
1048
|
if let dynamicApiKey = getDynamicApiKey(), !dynamicApiKey.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty {
|
package/package.json
CHANGED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
package ee.forgr.capacitor.streamcall
|
|
2
|
-
|
|
3
|
-
import android.app.Application
|
|
4
|
-
import android.app.NotificationManager
|
|
5
|
-
import android.content.Context
|
|
6
|
-
import android.media.AudioAttributes
|
|
7
|
-
import android.media.MediaPlayer
|
|
8
|
-
import android.media.RingtoneManager
|
|
9
|
-
import android.os.Handler
|
|
10
|
-
import android.os.Looper
|
|
11
|
-
import android.util.Log
|
|
12
|
-
import io.getstream.video.android.core.notifications.NotificationHandler
|
|
13
|
-
|
|
14
|
-
class RingtonePlayer(
|
|
15
|
-
private val application: Application,
|
|
16
|
-
private val cancelIncomingCallService: () -> Unit = { }
|
|
17
|
-
) {
|
|
18
|
-
companion object {
|
|
19
|
-
private const val DEFAULT_RINGTONE_DURATION = 30000L // 30 seconds in milliseconds
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
private var mediaPlayer: MediaPlayer? = null
|
|
23
|
-
private val handler = Handler(Looper.getMainLooper())
|
|
24
|
-
private var stopRingtoneRunnable: Runnable? = null
|
|
25
|
-
private var isPaused = false
|
|
26
|
-
private var isStopped = true
|
|
27
|
-
|
|
28
|
-
private fun isOurNotification(notification: android.service.notification.StatusBarNotification): Boolean {
|
|
29
|
-
return notification.id == NotificationHandler.INCOMING_CALL_NOTIFICATION_ID
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
fun pauseRinging() {
|
|
33
|
-
Log.d("RingtonePlayer", "Pause ringing")
|
|
34
|
-
// try {
|
|
35
|
-
// if (!isStopped) {
|
|
36
|
-
// mediaPlayer?.pause()
|
|
37
|
-
// isPaused = true
|
|
38
|
-
// }
|
|
39
|
-
// } catch (e: Exception) {
|
|
40
|
-
// Log.e("RingtonePlayer", "Error pausing ringtone: ${e.message}")
|
|
41
|
-
// }
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
fun resumeRinging() {
|
|
45
|
-
Log.d("RingtonePlayer", "Resume ringing")
|
|
46
|
-
// try {
|
|
47
|
-
// if (!isStopped && isPaused) {
|
|
48
|
-
// mediaPlayer?.start()
|
|
49
|
-
// isPaused = false
|
|
50
|
-
// }
|
|
51
|
-
// } catch (e: Exception) {
|
|
52
|
-
// Log.e("RingtonePlayer", "Error resuming ringtone: ${e.message}")
|
|
53
|
-
// }
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
fun isPaused(): Boolean {
|
|
57
|
-
return isPaused
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
fun startRinging() {
|
|
61
|
-
Log.d("RingtonePlayer", "Start ringing")
|
|
62
|
-
// try {
|
|
63
|
-
// isStopped = false
|
|
64
|
-
// isPaused = false
|
|
65
|
-
// if (mediaPlayer == null) {
|
|
66
|
-
// val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
|
67
|
-
// mediaPlayer = MediaPlayer().apply {
|
|
68
|
-
// setDataSource(application, uri)
|
|
69
|
-
// isLooping = true
|
|
70
|
-
// setAudioAttributes(
|
|
71
|
-
// AudioAttributes.Builder()
|
|
72
|
-
// .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
|
73
|
-
// .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
|
74
|
-
// .build()
|
|
75
|
-
// )
|
|
76
|
-
// prepare()
|
|
77
|
-
// }
|
|
78
|
-
// }
|
|
79
|
-
//
|
|
80
|
-
// val notificationManager = application.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
81
|
-
// val notifs = notificationManager.activeNotifications.toList()
|
|
82
|
-
// var notificationTime = 0L
|
|
83
|
-
//
|
|
84
|
-
// for (notification in notifs) {
|
|
85
|
-
// // First check if it's our notification
|
|
86
|
-
// val isOurs = isOurNotification(notification)
|
|
87
|
-
//
|
|
88
|
-
// // Only proceed with ringtone if it's our notification
|
|
89
|
-
// if (!isOurs) {
|
|
90
|
-
// Log.d("RingtonePlayer", "Skipping notification as it's not our incoming call notification")
|
|
91
|
-
// continue
|
|
92
|
-
// }
|
|
93
|
-
//
|
|
94
|
-
// // Cancel our notification
|
|
95
|
-
// try {
|
|
96
|
-
// Log.d("RingtonePlayer", "Canceling notification/service with id: ${notification.id}")
|
|
97
|
-
// this.cancelIncomingCallService()
|
|
98
|
-
// } catch (e: Exception) {
|
|
99
|
-
// Log.e("RingtonePlayer", "Error cancelling notification: ${e.message}")
|
|
100
|
-
// }
|
|
101
|
-
// notificationTime = notification.postTime
|
|
102
|
-
// }
|
|
103
|
-
//
|
|
104
|
-
// if (notificationTime > 0) {
|
|
105
|
-
// val currentTime = System.currentTimeMillis()
|
|
106
|
-
// val elapsedTime = currentTime - notificationTime
|
|
107
|
-
//
|
|
108
|
-
// // Only start playing if we're within the ringtone duration
|
|
109
|
-
// if (elapsedTime < DEFAULT_RINGTONE_DURATION) {
|
|
110
|
-
// // Get the ringtone duration
|
|
111
|
-
// val ringtoneDuration = mediaPlayer?.duration?.toLong() ?: DEFAULT_RINGTONE_DURATION
|
|
112
|
-
//
|
|
113
|
-
// // Calculate the position to seek to
|
|
114
|
-
// val seekPosition = (elapsedTime % ringtoneDuration).toInt()
|
|
115
|
-
// Log.d("RingtonePlayer", "Seeking to position: $seekPosition ms in ringtone")
|
|
116
|
-
//
|
|
117
|
-
// mediaPlayer?.seekTo(seekPosition)
|
|
118
|
-
// mediaPlayer?.start()
|
|
119
|
-
//
|
|
120
|
-
// // Schedule stop at the remaining duration
|
|
121
|
-
// val remainingDuration = DEFAULT_RINGTONE_DURATION - elapsedTime
|
|
122
|
-
// stopRingtoneRunnable = Runnable { stopRinging() }
|
|
123
|
-
// handler.postDelayed(stopRingtoneRunnable!!, remainingDuration)
|
|
124
|
-
//
|
|
125
|
-
// Log.d("RingtonePlayer", "Starting ringtone with offset: $elapsedTime ms, will play for $remainingDuration ms")
|
|
126
|
-
// } else {
|
|
127
|
-
// Log.d("RingtonePlayer", "Not starting ringtone as elapsed time ($elapsedTime ms) exceeds duration")
|
|
128
|
-
// }
|
|
129
|
-
// } else {
|
|
130
|
-
// // If no notification time found, just play normally
|
|
131
|
-
// mediaPlayer?.start()
|
|
132
|
-
//
|
|
133
|
-
// // Schedule stop at the default duration
|
|
134
|
-
// stopRingtoneRunnable = Runnable { stopRinging() }
|
|
135
|
-
// handler.postDelayed(stopRingtoneRunnable!!, DEFAULT_RINGTONE_DURATION)
|
|
136
|
-
//
|
|
137
|
-
// Log.d("RingtonePlayer", "Starting ringtone with default duration")
|
|
138
|
-
// }
|
|
139
|
-
// } catch (e: Exception) {
|
|
140
|
-
// Log.e("RingtonePlayer", "Error playing ringtone: ${e.message}")
|
|
141
|
-
// }
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
fun stopRinging() {
|
|
145
|
-
Log.d("RingtonePlayer", "Stop ringing")
|
|
146
|
-
// try {
|
|
147
|
-
// isStopped = true
|
|
148
|
-
// isPaused = false
|
|
149
|
-
// stopRingtoneRunnable?.let { handler.removeCallbacks(it) }
|
|
150
|
-
// stopRingtoneRunnable = null
|
|
151
|
-
//
|
|
152
|
-
// mediaPlayer?.stop()
|
|
153
|
-
// mediaPlayer?.reset()
|
|
154
|
-
// mediaPlayer?.release()
|
|
155
|
-
// mediaPlayer = null
|
|
156
|
-
// } catch (e: Exception) {
|
|
157
|
-
// Log.e("RingtonePlayer", "Error stopping ringtone: ${e.message}")
|
|
158
|
-
// }
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|