@capgo/capacitor-stream-call 0.0.51 → 0.0.62
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 +24 -14
- package/android/build.gradle +2 -2
- package/android/src/main/java/ee/forgr/capacitor/streamcall/CustomNotificationHandler.kt +4 -3
- package/android/src/main/java/ee/forgr/capacitor/streamcall/RingtonePlayer.kt +109 -109
- package/android/src/main/java/ee/forgr/capacitor/streamcall/StreamCallPlugin.kt +75 -90
- package/dist/docs.json +39 -0
- package/dist/esm/definitions.d.ts +7 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.js +9 -7
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +9 -7
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +9 -7
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/StreamCallPlugin/StreamCallPlugin.swift +63 -12
- package/ios/Sources/StreamCallPlugin/TouchInterceptView.swift +59 -2
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
|
|
|
13
13
|
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
14
|
s.ios.deployment_target = '14.0'
|
|
15
15
|
s.dependency 'Capacitor'
|
|
16
|
-
s.dependency 'StreamVideo', '1.
|
|
17
|
-
s.dependency 'StreamVideoSwiftUI', '1.
|
|
16
|
+
s.dependency 'StreamVideo', '1.24.0'
|
|
17
|
+
s.dependency 'StreamVideoSwiftUI', '1.24.0'
|
|
18
18
|
s.swift_version = '5.1'
|
|
19
19
|
end
|
package/Package.swift
CHANGED
|
@@ -11,7 +11,7 @@ let package = Package(
|
|
|
11
11
|
],
|
|
12
12
|
dependencies: [
|
|
13
13
|
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0"),
|
|
14
|
-
.package(url: "https://github.com/GetStream/stream-video-swift.git", exact: "1.
|
|
14
|
+
.package(url: "https://github.com/GetStream/stream-video-swift.git", exact: "1.24.0")
|
|
15
15
|
],
|
|
16
16
|
targets: [
|
|
17
17
|
.target(
|
package/README.md
CHANGED
|
@@ -518,24 +518,34 @@ Get detailed information about an active call including caller details
|
|
|
518
518
|
|
|
519
519
|
#### LoginOptions
|
|
520
520
|
|
|
521
|
-
| Prop
|
|
522
|
-
|
|
|
523
|
-
| **`token`**
|
|
524
|
-
| **`userId`**
|
|
525
|
-
| **`name`**
|
|
526
|
-
| **`imageURL`**
|
|
527
|
-
| **`apiKey`**
|
|
528
|
-
| **`magicDivId`**
|
|
521
|
+
| Prop | Type | Description |
|
|
522
|
+
| ----------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------- |
|
|
523
|
+
| **`token`** | <code>string</code> | Stream Video API token |
|
|
524
|
+
| **`userId`** | <code>string</code> | User ID for the current user |
|
|
525
|
+
| **`name`** | <code>string</code> | Display name for the current user |
|
|
526
|
+
| **`imageURL`** | <code>string</code> | Optional avatar URL for the current user |
|
|
527
|
+
| **`apiKey`** | <code>string</code> | Stream Video API key |
|
|
528
|
+
| **`magicDivId`** | <code>string</code> | ID of the HTML element where the video will be rendered |
|
|
529
|
+
| **`pushNotificationsConfig`** | <code><a href="#pushnotificationsconfig">PushNotificationsConfig</a></code> | |
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
#### PushNotificationsConfig
|
|
533
|
+
|
|
534
|
+
| Prop | Type |
|
|
535
|
+
| ---------------------- | ------------------- |
|
|
536
|
+
| **`pushProviderName`** | <code>string</code> |
|
|
537
|
+
| **`voipProviderName`** | <code>string</code> |
|
|
529
538
|
|
|
530
539
|
|
|
531
540
|
#### CallOptions
|
|
532
541
|
|
|
533
|
-
| Prop | Type | Description
|
|
534
|
-
| ------------- | --------------------------------------------- |
|
|
535
|
-
| **`userIds`** | <code>string[]</code> | User ID of the person to call
|
|
536
|
-
| **`type`** | <code><a href="#calltype">CallType</a></code> | Type of call, defaults to 'default'
|
|
537
|
-
| **`ring`** | <code>boolean</code> | Whether to ring the other user, defaults to true
|
|
538
|
-
| **`team`** | <code>string</code> | Team name to call
|
|
542
|
+
| Prop | Type | Description |
|
|
543
|
+
| ------------- | --------------------------------------------- | --------------------------------------------------------------- |
|
|
544
|
+
| **`userIds`** | <code>string[]</code> | User ID of the person to call |
|
|
545
|
+
| **`type`** | <code><a href="#calltype">CallType</a></code> | Type of call, defaults to 'default' |
|
|
546
|
+
| **`ring`** | <code>boolean</code> | Whether to ring the other user, defaults to true |
|
|
547
|
+
| **`team`** | <code>string</code> | Team name to call |
|
|
548
|
+
| **`video`** | <code>boolean</code> | Whether to start the call with video enabled, defaults to false |
|
|
539
549
|
|
|
540
550
|
|
|
541
551
|
#### CallEvent
|
package/android/build.gradle
CHANGED
|
@@ -75,8 +75,8 @@ dependencies {
|
|
|
75
75
|
implementation "androidx.compose.material3:material3:1.3.2"
|
|
76
76
|
|
|
77
77
|
// Stream dependencies
|
|
78
|
-
implementation("io.getstream:stream-video-android-ui-compose:1.6.
|
|
79
|
-
implementation("io.getstream:stream-video-android-core:1.6.
|
|
78
|
+
implementation("io.getstream:stream-video-android-ui-compose:1.6.3")
|
|
79
|
+
implementation("io.getstream:stream-video-android-core:1.6.3")
|
|
80
80
|
implementation("io.getstream:stream-android-push:1.3.1")
|
|
81
81
|
implementation("io.getstream:stream-android-push-firebase:1.3.1")
|
|
82
82
|
|
|
@@ -13,7 +13,8 @@ import io.getstream.video.android.core.RingingState
|
|
|
13
13
|
import io.getstream.video.android.core.notifications.DefaultNotificationHandler
|
|
14
14
|
import io.getstream.video.android.core.notifications.NotificationHandler
|
|
15
15
|
import io.getstream.video.android.model.StreamCallId
|
|
16
|
-
|
|
16
|
+
import io.getstream.video.android.model.streamCallId
|
|
17
|
+
|
|
17
18
|
// declare "incoming_calls_custom" as a constant
|
|
18
19
|
const val INCOMING_CALLS_CUSTOM = "incoming_calls_custom"
|
|
19
20
|
|
|
@@ -76,7 +77,7 @@ class CustomNotificationHandler(
|
|
|
76
77
|
}
|
|
77
78
|
acceptCallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
78
79
|
|
|
79
|
-
Log.d("CustomNotificationHandler", "Constructed Accept Call Intent for PI: action=${acceptCallIntent.action}, cid=${acceptCallIntent.
|
|
80
|
+
Log.d("CustomNotificationHandler", "Constructed Accept Call Intent for PI: action=${acceptCallIntent.action}, cid=${acceptCallIntent.streamCallId(NotificationHandler.INTENT_EXTRA_CALL_CID)}, package=${acceptCallIntent.getPackage()}, component=${acceptCallIntent.component?.flattenToString()}, flags=${acceptCallIntent.flags}")
|
|
80
81
|
|
|
81
82
|
// Create PendingIntent for Accept action using getActivity to launch the app
|
|
82
83
|
val requestCodeAccept = callId.cid.hashCode() + 1 // Unique request code for the PendingIntent with offset to avoid collisions
|
|
@@ -150,7 +151,7 @@ class CustomNotificationHandler(
|
|
|
150
151
|
)
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
fun buildNotification(
|
|
154
|
+
private fun buildNotification(
|
|
154
155
|
fullScreenPendingIntent: PendingIntent,
|
|
155
156
|
acceptCallPendingIntent: PendingIntent,
|
|
156
157
|
rejectCallPendingIntent: PendingIntent,
|
|
@@ -31,26 +31,26 @@ class RingtonePlayer(
|
|
|
31
31
|
|
|
32
32
|
fun pauseRinging() {
|
|
33
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
|
-
}
|
|
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
42
|
}
|
|
43
43
|
|
|
44
44
|
fun resumeRinging() {
|
|
45
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
|
-
}
|
|
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
54
|
}
|
|
55
55
|
|
|
56
56
|
fun isPaused(): Boolean {
|
|
@@ -59,103 +59,103 @@ class RingtonePlayer(
|
|
|
59
59
|
|
|
60
60
|
fun startRinging() {
|
|
61
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
|
-
}
|
|
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
142
|
}
|
|
143
143
|
|
|
144
144
|
fun stopRinging() {
|
|
145
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
|
-
}
|
|
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
159
|
}
|
|
160
160
|
|
|
161
161
|
|