@capgo/capacitor-stream-call 0.0.71 → 0.0.77
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/README.md +61 -12
- package/android/src/main/java/ee/forgr/capacitor/streamcall/JSObjectExtension.kt +38 -0
- package/android/src/main/java/ee/forgr/capacitor/streamcall/StreamCallPlugin.kt +109 -7
- package/dist/docs.json +124 -0
- package/dist/esm/definitions.d.ts +38 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +5 -1
- package/dist/esm/web.js +6 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +6 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +6 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/StreamCallPlugin/StreamCallPlugin.swift +123 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -252,6 +252,8 @@ export class CallService {
|
|
|
252
252
|
* [`setSpeaker(...)`](#setspeaker)
|
|
253
253
|
* [`switchCamera(...)`](#switchcamera)
|
|
254
254
|
* [`getCallInfo(...)`](#getcallinfo)
|
|
255
|
+
* [`setDynamicStreamVideoApikey(...)`](#setdynamicstreamvideoapikey)
|
|
256
|
+
* [`getDynamicStreamVideoApikey()`](#getdynamicstreamvideoapikey)
|
|
255
257
|
* [Interfaces](#interfaces)
|
|
256
258
|
* [Type Aliases](#type-aliases)
|
|
257
259
|
* [Enums](#enums)
|
|
@@ -506,6 +508,36 @@ Get detailed information about an active call including caller details
|
|
|
506
508
|
--------------------
|
|
507
509
|
|
|
508
510
|
|
|
511
|
+
### setDynamicStreamVideoApikey(...)
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
setDynamicStreamVideoApikey(options: { apiKey: string; }) => Promise<SuccessResponse>
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Set a dynamic Stream Video API key that overrides the static one
|
|
518
|
+
|
|
519
|
+
| Param | Type | Description |
|
|
520
|
+
| ------------- | -------------------------------- | -------------------- |
|
|
521
|
+
| **`options`** | <code>{ apiKey: string; }</code> | - The API key to set |
|
|
522
|
+
|
|
523
|
+
**Returns:** <code>Promise<<a href="#successresponse">SuccessResponse</a>></code>
|
|
524
|
+
|
|
525
|
+
--------------------
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
### getDynamicStreamVideoApikey()
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
getDynamicStreamVideoApikey() => Promise<DynamicApiKeyResponse>
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Get the currently set dynamic Stream Video API key
|
|
535
|
+
|
|
536
|
+
**Returns:** <code>Promise<<a href="#dynamicapikeyresponse">DynamicApiKeyResponse</a>></code>
|
|
537
|
+
|
|
538
|
+
--------------------
|
|
539
|
+
|
|
540
|
+
|
|
509
541
|
### Interfaces
|
|
510
542
|
|
|
511
543
|
|
|
@@ -539,13 +571,14 @@ Get detailed information about an active call including caller details
|
|
|
539
571
|
|
|
540
572
|
#### CallOptions
|
|
541
573
|
|
|
542
|
-
| Prop | Type
|
|
543
|
-
| ------------- |
|
|
544
|
-
| **`userIds`** | <code>string[]</code>
|
|
545
|
-
| **`type`** | <code><a href="#calltype">CallType</a></code>
|
|
546
|
-
| **`ring`** | <code>boolean</code>
|
|
547
|
-
| **`team`** | <code>string</code>
|
|
548
|
-
| **`video`** | <code>boolean</code>
|
|
574
|
+
| Prop | Type | Description |
|
|
575
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
576
|
+
| **`userIds`** | <code>string[]</code> | User ID of the person to call |
|
|
577
|
+
| **`type`** | <code><a href="#calltype">CallType</a></code> | Type of call, defaults to 'default' |
|
|
578
|
+
| **`ring`** | <code>boolean</code> | Whether to ring the other user, defaults to true |
|
|
579
|
+
| **`team`** | <code>string</code> | Team name to call |
|
|
580
|
+
| **`video`** | <code>boolean</code> | Whether to start the call with video enabled, defaults to false |
|
|
581
|
+
| **`custom`** | <code><a href="#record">Record</a>< string, \| string \| boolean \| number \| null \| <a href="#record">Record</a><string, string \| boolean \| number \| null> \| string[] \| boolean[] \| number[] ></code> | Custom data to be passed to the call |
|
|
549
582
|
|
|
550
583
|
|
|
551
584
|
#### CallEvent
|
|
@@ -763,11 +796,12 @@ The JSON representation for <a href="#listvalue">`ListValue`</a> is JSON array.
|
|
|
763
796
|
|
|
764
797
|
#### IncomingCallPayload
|
|
765
798
|
|
|
766
|
-
| Prop | Type
|
|
767
|
-
| ------------ |
|
|
768
|
-
| **`cid`** | <code>string</code>
|
|
769
|
-
| **`type`** | <code>'incoming'</code>
|
|
770
|
-
| **`caller`** | <code><a href="#callmember">CallMember</a></code>
|
|
799
|
+
| Prop | Type | Description |
|
|
800
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
|
|
801
|
+
| **`cid`** | <code>string</code> | Full call CID (e.g. default:123) |
|
|
802
|
+
| **`type`** | <code>'incoming'</code> | Event type (currently always "incoming") |
|
|
803
|
+
| **`caller`** | <code><a href="#callmember">CallMember</a></code> | Information about the caller |
|
|
804
|
+
| **`custom`** | <code><a href="#record">Record</a>< string, \| string \| boolean \| number \| null \| <a href="#record">Record</a><string, string \| boolean \| number \| null> \| string[] \| boolean[] \| number[] ></code> | Custom data to be passed to the call |
|
|
771
805
|
|
|
772
806
|
|
|
773
807
|
#### CameraEnabledResponse
|
|
@@ -777,6 +811,14 @@ The JSON representation for <a href="#listvalue">`ListValue`</a> is JSON array.
|
|
|
777
811
|
| **`enabled`** | <code>boolean</code> |
|
|
778
812
|
|
|
779
813
|
|
|
814
|
+
#### DynamicApiKeyResponse
|
|
815
|
+
|
|
816
|
+
| Prop | Type | Description |
|
|
817
|
+
| ------------------- | --------------------------- | --------------------------------------- |
|
|
818
|
+
| **`apiKey`** | <code>string \| null</code> | The dynamic API key if set, null if not |
|
|
819
|
+
| **`hasDynamicKey`** | <code>boolean</code> | Whether a dynamic key is currently set |
|
|
820
|
+
|
|
821
|
+
|
|
780
822
|
### Type Aliases
|
|
781
823
|
|
|
782
824
|
|
|
@@ -785,6 +827,13 @@ The JSON representation for <a href="#listvalue">`ListValue`</a> is JSON array.
|
|
|
785
827
|
<code>'default' | 'audio_room' | 'livestream' | 'development'</code>
|
|
786
828
|
|
|
787
829
|
|
|
830
|
+
#### Record
|
|
831
|
+
|
|
832
|
+
Construct a type with a set of properties K of type T
|
|
833
|
+
|
|
834
|
+
<code>{
|
|
788
835
|
[P in K]: T;
|
|
789
836
|
}</code>
|
|
837
|
+
|
|
838
|
+
|
|
790
839
|
#### CallState
|
|
791
840
|
|
|
792
841
|
<code>'idle' | 'ringing' | 'joining' | 'reconnecting' | 'joined' | 'leaving' | 'left' | 'created' | 'session_started' | 'rejected' | 'missed' | 'accepted' | 'ended' | 'camera_enabled' | 'camera_disabled' | 'microphone_enabled' | 'microphone_disabled' | 'unknown'</code>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package ee.forgr.capacitor.streamcall
|
|
2
|
+
|
|
3
|
+
import org.json.JSONArray
|
|
4
|
+
import org.json.JSONObject
|
|
5
|
+
|
|
6
|
+
fun JSONObject.toMap(): Map<String, Any> {
|
|
7
|
+
val map = mutableMapOf<String, Any>()
|
|
8
|
+
val keys = this.keys()
|
|
9
|
+
while (keys.hasNext()) {
|
|
10
|
+
val key = keys.next()
|
|
11
|
+
var value = this.get(key)
|
|
12
|
+
|
|
13
|
+
// Handle nested JSONObjects and JSONArrays
|
|
14
|
+
value = when (value) {
|
|
15
|
+
is JSONObject -> value.toMap()
|
|
16
|
+
is JSONArray -> value.toList()
|
|
17
|
+
else -> value
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
map[key] = value
|
|
21
|
+
}
|
|
22
|
+
return map
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Helper for JSONArray
|
|
26
|
+
fun JSONArray.toList(): List<Any> {
|
|
27
|
+
val list = mutableListOf<Any>()
|
|
28
|
+
for (i in 0 until this.length()) {
|
|
29
|
+
var value = this.get(i)
|
|
30
|
+
value = when (value) {
|
|
31
|
+
is JSONObject -> value.toMap()
|
|
32
|
+
is JSONArray -> value.toList()
|
|
33
|
+
else -> value
|
|
34
|
+
}
|
|
35
|
+
list.add(value)
|
|
36
|
+
}
|
|
37
|
+
return list
|
|
38
|
+
}
|
|
@@ -10,6 +10,7 @@ import android.content.BroadcastReceiver
|
|
|
10
10
|
import android.content.Context
|
|
11
11
|
import android.content.Intent
|
|
12
12
|
import android.content.IntentFilter
|
|
13
|
+
import android.content.SharedPreferences
|
|
13
14
|
import android.content.pm.PackageManager
|
|
14
15
|
import android.graphics.Color
|
|
15
16
|
import android.media.RingtoneManager
|
|
@@ -83,6 +84,7 @@ import kotlinx.coroutines.Dispatchers
|
|
|
83
84
|
import kotlinx.coroutines.launch
|
|
84
85
|
import kotlinx.coroutines.tasks.await
|
|
85
86
|
import androidx.core.net.toUri
|
|
87
|
+
import org.json.JSONObject
|
|
86
88
|
|
|
87
89
|
// I am not a religious pearson, but at this point, I am not sure even god himself would understand this code
|
|
88
90
|
// It's a spaghetti-like, tangled, unreadable mess and frankly, I am deeply sorry for the code crimes commited in the Android impl
|
|
@@ -121,6 +123,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
121
123
|
private var pendingCallType: String? = null
|
|
122
124
|
private var pendingCallShouldRing: Boolean? = null
|
|
123
125
|
private var pendingCallTeam: String? = null
|
|
126
|
+
private var pendingCustomObject: JSObject? = null
|
|
124
127
|
private var pendingAcceptCall: Call? = null // Store the actual call object for acceptance
|
|
125
128
|
|
|
126
129
|
private enum class State {
|
|
@@ -228,6 +231,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
228
231
|
try {
|
|
229
232
|
val callInfo = call?.get()
|
|
230
233
|
val callerInfo = callInfo?.getOrNull()?.call?.createdBy
|
|
234
|
+
val custom = callInfo?.getOrNull()?.call?.custom
|
|
231
235
|
|
|
232
236
|
val payload = com.getcapacitor.JSObject().apply {
|
|
233
237
|
put("cid", cid.cid)
|
|
@@ -241,6 +245,9 @@ public class StreamCallPlugin : Plugin() {
|
|
|
241
245
|
}
|
|
242
246
|
put("caller", caller)
|
|
243
247
|
}
|
|
248
|
+
if (custom != null) {
|
|
249
|
+
put("custom", JSONObject(custom))
|
|
250
|
+
}
|
|
244
251
|
}
|
|
245
252
|
|
|
246
253
|
// Notify WebView/JS about incoming call so it can render its own UI
|
|
@@ -449,9 +456,10 @@ public class StreamCallPlugin : Plugin() {
|
|
|
449
456
|
val token = call.getString("token")
|
|
450
457
|
val userId = call.getString("userId")
|
|
451
458
|
val name = call.getString("name")
|
|
459
|
+
val apiKey = call.getString("apiKey")
|
|
452
460
|
|
|
453
|
-
if (token == null || userId == null || name == null) {
|
|
454
|
-
call.reject("Missing required parameters: token, userId, or
|
|
461
|
+
if (token == null || userId == null || name == null || apiKey == null) {
|
|
462
|
+
call.reject("Missing required parameters: token, userId, name, or apiKey")
|
|
455
463
|
return
|
|
456
464
|
}
|
|
457
465
|
|
|
@@ -614,7 +622,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
614
622
|
// Initialize StreamVideo client
|
|
615
623
|
streamVideoClient = StreamVideoBuilder(
|
|
616
624
|
context = contextToUse,
|
|
617
|
-
apiKey = contextToUse
|
|
625
|
+
apiKey = getEffectiveApiKey(contextToUse),
|
|
618
626
|
geo = GEO.GlobalEdgeNetwork,
|
|
619
627
|
user = savedCredentials.user,
|
|
620
628
|
token = savedCredentials.tokenValue,
|
|
@@ -1355,6 +1363,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1355
1363
|
val callType = pendingCallType
|
|
1356
1364
|
val shouldRing = pendingCallShouldRing
|
|
1357
1365
|
val team = pendingCallTeam
|
|
1366
|
+
val custom = pendingCustomObject
|
|
1358
1367
|
|
|
1359
1368
|
if (call != null && userIds != null && callType != null && shouldRing != null) {
|
|
1360
1369
|
android.util.Log.d("StreamCallPlugin", "executePendingCall: Executing call with ${userIds.size} users")
|
|
@@ -1363,7 +1372,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1363
1372
|
clearPendingCall()
|
|
1364
1373
|
|
|
1365
1374
|
// Execute the call creation logic
|
|
1366
|
-
createAndStartCall(call, userIds, callType, shouldRing, team)
|
|
1375
|
+
createAndStartCall(call, userIds, callType, shouldRing, team, custom)
|
|
1367
1376
|
} else {
|
|
1368
1377
|
android.util.Log.w("StreamCallPlugin", "executePendingCall: Missing pending call data")
|
|
1369
1378
|
call?.reject("Internal error: missing call parameters")
|
|
@@ -1378,11 +1387,14 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1378
1387
|
pendingCallShouldRing = null
|
|
1379
1388
|
pendingCallTeam = null
|
|
1380
1389
|
pendingAcceptCall = null
|
|
1390
|
+
pendingCallTeam = null
|
|
1381
1391
|
permissionAttemptCount = 0 // Reset attempt count when clearing
|
|
1382
1392
|
}
|
|
1383
1393
|
|
|
1394
|
+
|
|
1395
|
+
|
|
1384
1396
|
@OptIn(DelicateCoroutinesApi::class, InternalStreamVideoApi::class)
|
|
1385
|
-
private fun createAndStartCall(call: PluginCall, userIds: List<String>, callType: String, shouldRing: Boolean, team: String?) {
|
|
1397
|
+
private fun createAndStartCall(call: PluginCall, userIds: List<String>, callType: String, shouldRing: Boolean, team: String?, custom: JSObject?) {
|
|
1386
1398
|
val selfUserId = streamVideoClient?.userId
|
|
1387
1399
|
if (selfUserId == null) {
|
|
1388
1400
|
call.reject("No self-user id found. Are you not logged in?")
|
|
@@ -1400,11 +1412,12 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1400
1412
|
// Note: We no longer start tracking here - we'll wait for CallSessionStartedEvent
|
|
1401
1413
|
// instead, which contains the actual participant list
|
|
1402
1414
|
|
|
1415
|
+
|
|
1403
1416
|
android.util.Log.d("StreamCallPlugin", "Creating call with members...")
|
|
1404
1417
|
// Create the call with all members
|
|
1405
1418
|
val createResult = streamCall?.create(
|
|
1406
1419
|
memberIds = userIds + selfUserId,
|
|
1407
|
-
custom = emptyMap(),
|
|
1420
|
+
custom = custom?.toMap() ?: emptyMap(),
|
|
1408
1421
|
ring = shouldRing,
|
|
1409
1422
|
team = team,
|
|
1410
1423
|
)
|
|
@@ -1924,6 +1937,8 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1924
1937
|
return
|
|
1925
1938
|
}
|
|
1926
1939
|
|
|
1940
|
+
val custom = call.getObject("custom")
|
|
1941
|
+
|
|
1927
1942
|
try {
|
|
1928
1943
|
if (state != State.INITIALIZED) {
|
|
1929
1944
|
call.reject("StreamVideo not initialized")
|
|
@@ -1946,6 +1961,9 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1946
1961
|
android.util.Log.d("StreamCallPlugin", "- Call Type: $callType")
|
|
1947
1962
|
android.util.Log.d("StreamCallPlugin", "- Users: $userIds")
|
|
1948
1963
|
android.util.Log.d("StreamCallPlugin", "- Should Ring: $shouldRing")
|
|
1964
|
+
if (custom != null) {
|
|
1965
|
+
android.util.Log.d("StreamCallPlugin", "- Custom data: $custom")
|
|
1966
|
+
}
|
|
1949
1967
|
|
|
1950
1968
|
// Check permissions before creating the call
|
|
1951
1969
|
if (!checkPermissions()) {
|
|
@@ -1956,6 +1974,9 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1956
1974
|
pendingCallType = callType
|
|
1957
1975
|
pendingCallShouldRing = shouldRing
|
|
1958
1976
|
pendingCallTeam = team
|
|
1977
|
+
custom?.let {
|
|
1978
|
+
pendingCustomObject = it
|
|
1979
|
+
}
|
|
1959
1980
|
// Reset attempt count for new permission flow
|
|
1960
1981
|
permissionAttemptCount = 0
|
|
1961
1982
|
requestPermissions()
|
|
@@ -1963,7 +1984,7 @@ public class StreamCallPlugin : Plugin() {
|
|
|
1963
1984
|
}
|
|
1964
1985
|
|
|
1965
1986
|
// Execute call creation immediately if permissions are granted
|
|
1966
|
-
createAndStartCall(call, userIds, callType, shouldRing, team)
|
|
1987
|
+
createAndStartCall(call, userIds, callType, shouldRing, team, custom)
|
|
1967
1988
|
} catch (e: Exception) {
|
|
1968
1989
|
call.reject("Failed to make call: ${e.message}")
|
|
1969
1990
|
}
|
|
@@ -2180,6 +2201,83 @@ public class StreamCallPlugin : Plugin() {
|
|
|
2180
2201
|
}
|
|
2181
2202
|
}
|
|
2182
2203
|
|
|
2204
|
+
@PluginMethod
|
|
2205
|
+
fun setDynamicStreamVideoApikey(call: PluginCall) {
|
|
2206
|
+
val apiKey = call.getString("apiKey")
|
|
2207
|
+
if (apiKey == null) {
|
|
2208
|
+
call.reject("Missing required parameter: apiKey")
|
|
2209
|
+
return
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
try {
|
|
2213
|
+
saveDynamicApiKey(apiKey)
|
|
2214
|
+
android.util.Log.d("StreamCallPlugin", "Dynamic API key saved successfully")
|
|
2215
|
+
call.resolve(JSObject().apply {
|
|
2216
|
+
put("success", true)
|
|
2217
|
+
})
|
|
2218
|
+
} catch (e: Exception) {
|
|
2219
|
+
android.util.Log.e("StreamCallPlugin", "Error saving dynamic API key", e)
|
|
2220
|
+
call.reject("Failed to save API key: ${e.message}")
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
@PluginMethod
|
|
2225
|
+
fun getDynamicStreamVideoApikey(call: PluginCall) {
|
|
2226
|
+
try {
|
|
2227
|
+
val apiKey = getDynamicApiKey()
|
|
2228
|
+
call.resolve(JSObject().apply {
|
|
2229
|
+
if (apiKey != null) {
|
|
2230
|
+
put("apiKey", apiKey)
|
|
2231
|
+
put("hasDynamicKey", true)
|
|
2232
|
+
} else {
|
|
2233
|
+
put("apiKey", null)
|
|
2234
|
+
put("hasDynamicKey", false)
|
|
2235
|
+
}
|
|
2236
|
+
})
|
|
2237
|
+
} catch (e: Exception) {
|
|
2238
|
+
android.util.Log.e("StreamCallPlugin", "Error getting dynamic API key", e)
|
|
2239
|
+
call.reject("Failed to get API key: ${e.message}")
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
// Helper functions for managing dynamic API key in SharedPreferences
|
|
2244
|
+
private fun saveDynamicApiKey(apiKey: String) {
|
|
2245
|
+
val sharedPrefs = getApiKeyPreferences()
|
|
2246
|
+
sharedPrefs.edit()
|
|
2247
|
+
.putString(DYNAMIC_API_KEY_PREF, apiKey)
|
|
2248
|
+
.apply()
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
// Helper functions for managing dynamic API key in SharedPreferences
|
|
2252
|
+
private fun clearDynamicApiKey() {
|
|
2253
|
+
val sharedPrefs = getApiKeyPreferences()
|
|
2254
|
+
sharedPrefs.edit()
|
|
2255
|
+
.remove(DYNAMIC_API_KEY_PREF)
|
|
2256
|
+
.apply()
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
private fun getDynamicApiKey(): String? {
|
|
2260
|
+
val sharedPrefs = getApiKeyPreferences()
|
|
2261
|
+
return sharedPrefs.getString(DYNAMIC_API_KEY_PREF, null)
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
private fun getApiKeyPreferences(): SharedPreferences {
|
|
2265
|
+
return context.getSharedPreferences(API_KEY_PREFS_NAME, Context.MODE_PRIVATE)
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
private fun getEffectiveApiKey(context: Context): String {
|
|
2269
|
+
// A) Check if the key exists in the custom preference
|
|
2270
|
+
val dynamicApiKey = getDynamicApiKey()
|
|
2271
|
+
return if (!dynamicApiKey.isNullOrEmpty() && dynamicApiKey.trim().isNotEmpty()) {
|
|
2272
|
+
android.util.Log.d("StreamCallPlugin", "Using dynamic API key")
|
|
2273
|
+
dynamicApiKey
|
|
2274
|
+
} else {
|
|
2275
|
+
// B) If not, use R.string.CAPACITOR_STREAM_VIDEO_APIKEY
|
|
2276
|
+
android.util.Log.d("StreamCallPlugin", "Using static API key from resources")
|
|
2277
|
+
context.getString(R.string.CAPACITOR_STREAM_VIDEO_APIKEY)
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2183
2281
|
// Helper method to update call status and notify listeners
|
|
2184
2282
|
private fun updateCallStatusAndNotify(callId: String, state: String, userId: String? = null, reason: String? = null, members: List<Map<String, Any>>? = null, caller: Map<String, Any>? = null) {
|
|
2185
2283
|
android.util.Log.d("StreamCallPlugin", "updateCallStatusAndNotify called: callId=$callId, state=$state, userId=$userId, reason=$reason")
|
|
@@ -2314,5 +2412,9 @@ public class StreamCallPlugin : Plugin() {
|
|
|
2314
2412
|
}
|
|
2315
2413
|
}
|
|
2316
2414
|
private var holder: StreamCallPlugin? = null
|
|
2415
|
+
|
|
2416
|
+
// Constants for SharedPreferences
|
|
2417
|
+
private const val API_KEY_PREFS_NAME = "stream_video_api_key_prefs"
|
|
2418
|
+
private const val DYNAMIC_API_KEY_PREF = "dynamic_api_key"
|
|
2317
2419
|
}
|
|
2318
2420
|
}
|
package/dist/docs.json
CHANGED
|
@@ -431,6 +431,58 @@
|
|
|
431
431
|
"CallEvent"
|
|
432
432
|
],
|
|
433
433
|
"slug": "getcallinfo"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
"name": "setDynamicStreamVideoApikey",
|
|
437
|
+
"signature": "(options: { apiKey: string; }) => Promise<SuccessResponse>",
|
|
438
|
+
"parameters": [
|
|
439
|
+
{
|
|
440
|
+
"name": "options",
|
|
441
|
+
"docs": "- The API key to set",
|
|
442
|
+
"type": "{ apiKey: string; }"
|
|
443
|
+
}
|
|
444
|
+
],
|
|
445
|
+
"returns": "Promise<SuccessResponse>",
|
|
446
|
+
"tags": [
|
|
447
|
+
{
|
|
448
|
+
"name": "param",
|
|
449
|
+
"text": "options - The API key to set"
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"name": "returns",
|
|
453
|
+
"text": "Success status"
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
"name": "example",
|
|
457
|
+
"text": "await StreamCall.setDynamicStreamVideoApikey({ apiKey: 'new-api-key' });"
|
|
458
|
+
}
|
|
459
|
+
],
|
|
460
|
+
"docs": "Set a dynamic Stream Video API key that overrides the static one",
|
|
461
|
+
"complexTypes": [
|
|
462
|
+
"SuccessResponse"
|
|
463
|
+
],
|
|
464
|
+
"slug": "setdynamicstreamvideoapikey"
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
"name": "getDynamicStreamVideoApikey",
|
|
468
|
+
"signature": "() => Promise<DynamicApiKeyResponse>",
|
|
469
|
+
"parameters": [],
|
|
470
|
+
"returns": "Promise<DynamicApiKeyResponse>",
|
|
471
|
+
"tags": [
|
|
472
|
+
{
|
|
473
|
+
"name": "returns",
|
|
474
|
+
"text": "The dynamic API key and whether it's set"
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"name": "example",
|
|
478
|
+
"text": "const result = await StreamCall.getDynamicStreamVideoApikey();\nif (result.hasDynamicKey) {\n console.log('Dynamic API key:', result.apiKey);\n} else {\n console.log('Using static API key from resources');\n}"
|
|
479
|
+
}
|
|
480
|
+
],
|
|
481
|
+
"docs": "Get the currently set dynamic Stream Video API key",
|
|
482
|
+
"complexTypes": [
|
|
483
|
+
"DynamicApiKeyResponse"
|
|
484
|
+
],
|
|
485
|
+
"slug": "getdynamicstreamvideoapikey"
|
|
434
486
|
}
|
|
435
487
|
],
|
|
436
488
|
"properties": []
|
|
@@ -649,6 +701,15 @@
|
|
|
649
701
|
"docs": "Whether to start the call with video enabled, defaults to false",
|
|
650
702
|
"complexTypes": [],
|
|
651
703
|
"type": "boolean | undefined"
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"name": "custom",
|
|
707
|
+
"tags": [],
|
|
708
|
+
"docs": "Custom data to be passed to the call",
|
|
709
|
+
"complexTypes": [
|
|
710
|
+
"Record"
|
|
711
|
+
],
|
|
712
|
+
"type": "Record<\n string,\n | string\n | boolean\n | number\n | null\n | Record<string, string | boolean | number | null>\n | string[]\n | boolean[]\n | number[]\n >"
|
|
652
713
|
}
|
|
653
714
|
]
|
|
654
715
|
},
|
|
@@ -1334,6 +1395,15 @@
|
|
|
1334
1395
|
"CallMember"
|
|
1335
1396
|
],
|
|
1336
1397
|
"type": "CallMember"
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
"name": "custom",
|
|
1401
|
+
"tags": [],
|
|
1402
|
+
"docs": "Custom data to be passed to the call",
|
|
1403
|
+
"complexTypes": [
|
|
1404
|
+
"Record"
|
|
1405
|
+
],
|
|
1406
|
+
"type": "Record<\n string,\n | string\n | boolean\n | number\n | null\n | Record<string, string | boolean | number | null>\n | string[]\n | boolean[]\n | number[]\n >"
|
|
1337
1407
|
}
|
|
1338
1408
|
]
|
|
1339
1409
|
},
|
|
@@ -1352,6 +1422,46 @@
|
|
|
1352
1422
|
"type": "boolean"
|
|
1353
1423
|
}
|
|
1354
1424
|
]
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
"name": "DynamicApiKeyResponse",
|
|
1428
|
+
"slug": "dynamicapikeyresponse",
|
|
1429
|
+
"docs": "",
|
|
1430
|
+
"tags": [
|
|
1431
|
+
{
|
|
1432
|
+
"text": "DynamicApiKeyResponse",
|
|
1433
|
+
"name": "interface"
|
|
1434
|
+
},
|
|
1435
|
+
{
|
|
1436
|
+
"text": "Response from getDynamicStreamVideoApikey",
|
|
1437
|
+
"name": "description"
|
|
1438
|
+
},
|
|
1439
|
+
{
|
|
1440
|
+
"text": "{string|null} apiKey - The dynamic API key if set, null if not",
|
|
1441
|
+
"name": "property"
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
"text": "{boolean} hasDynamicKey - Whether a dynamic key is currently set",
|
|
1445
|
+
"name": "property"
|
|
1446
|
+
}
|
|
1447
|
+
],
|
|
1448
|
+
"methods": [],
|
|
1449
|
+
"properties": [
|
|
1450
|
+
{
|
|
1451
|
+
"name": "apiKey",
|
|
1452
|
+
"tags": [],
|
|
1453
|
+
"docs": "The dynamic API key if set, null if not",
|
|
1454
|
+
"complexTypes": [],
|
|
1455
|
+
"type": "string | null"
|
|
1456
|
+
},
|
|
1457
|
+
{
|
|
1458
|
+
"name": "hasDynamicKey",
|
|
1459
|
+
"tags": [],
|
|
1460
|
+
"docs": "Whether a dynamic key is currently set",
|
|
1461
|
+
"complexTypes": [],
|
|
1462
|
+
"type": "boolean"
|
|
1463
|
+
}
|
|
1464
|
+
]
|
|
1355
1465
|
}
|
|
1356
1466
|
],
|
|
1357
1467
|
"enums": [
|
|
@@ -1508,6 +1618,20 @@
|
|
|
1508
1618
|
}
|
|
1509
1619
|
]
|
|
1510
1620
|
},
|
|
1621
|
+
{
|
|
1622
|
+
"name": "Record",
|
|
1623
|
+
"slug": "record",
|
|
1624
|
+
"docs": "Construct a type with a set of properties K of type T",
|
|
1625
|
+
"types": [
|
|
1626
|
+
{
|
|
1627
|
+
"text": "{\r\n [P in K]: T;\r\n}",
|
|
1628
|
+
"complexTypes": [
|
|
1629
|
+
"K",
|
|
1630
|
+
"T"
|
|
1631
|
+
]
|
|
1632
|
+
}
|
|
1633
|
+
]
|
|
1634
|
+
},
|
|
1511
1635
|
{
|
|
1512
1636
|
"name": "CallState",
|
|
1513
1637
|
"slug": "callstate",
|
|
@@ -86,6 +86,18 @@ export interface CallEvent {
|
|
|
86
86
|
export interface CameraEnabledResponse {
|
|
87
87
|
enabled: boolean;
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* @interface DynamicApiKeyResponse
|
|
91
|
+
* @description Response from getDynamicStreamVideoApikey
|
|
92
|
+
* @property {string|null} apiKey - The dynamic API key if set, null if not
|
|
93
|
+
* @property {boolean} hasDynamicKey - Whether a dynamic key is currently set
|
|
94
|
+
*/
|
|
95
|
+
export interface DynamicApiKeyResponse {
|
|
96
|
+
/** The dynamic API key if set, null if not */
|
|
97
|
+
apiKey: string | null;
|
|
98
|
+
/** Whether a dynamic key is currently set */
|
|
99
|
+
hasDynamicKey: boolean;
|
|
100
|
+
}
|
|
89
101
|
/**
|
|
90
102
|
* @interface SuccessResponse
|
|
91
103
|
* @description Standard response indicating operation success/failure
|
|
@@ -114,6 +126,8 @@ export interface CallOptions {
|
|
|
114
126
|
team?: string;
|
|
115
127
|
/** Whether to start the call with video enabled, defaults to false */
|
|
116
128
|
video?: boolean;
|
|
129
|
+
/** Custom data to be passed to the call */
|
|
130
|
+
custom?: Record<string, string | boolean | number | null | Record<string, string | boolean | number | null> | string[] | boolean[] | number[]>;
|
|
117
131
|
}
|
|
118
132
|
/**
|
|
119
133
|
* @interface StreamCallPlugin
|
|
@@ -263,6 +277,28 @@ export interface StreamCallPlugin {
|
|
|
263
277
|
getCallInfo(options: {
|
|
264
278
|
callId: string;
|
|
265
279
|
}): Promise<CallEvent>;
|
|
280
|
+
/**
|
|
281
|
+
* Set a dynamic Stream Video API key that overrides the static one
|
|
282
|
+
* @param {{ apiKey: string }} options - The API key to set
|
|
283
|
+
* @returns {Promise<SuccessResponse>} Success status
|
|
284
|
+
* @example
|
|
285
|
+
* await StreamCall.setDynamicStreamVideoApikey({ apiKey: 'new-api-key' });
|
|
286
|
+
*/
|
|
287
|
+
setDynamicStreamVideoApikey(options: {
|
|
288
|
+
apiKey: string;
|
|
289
|
+
}): Promise<SuccessResponse>;
|
|
290
|
+
/**
|
|
291
|
+
* Get the currently set dynamic Stream Video API key
|
|
292
|
+
* @returns {Promise<DynamicApiKeyResponse>} The dynamic API key and whether it's set
|
|
293
|
+
* @example
|
|
294
|
+
* const result = await StreamCall.getDynamicStreamVideoApikey();
|
|
295
|
+
* if (result.hasDynamicKey) {
|
|
296
|
+
* console.log('Dynamic API key:', result.apiKey);
|
|
297
|
+
* } else {
|
|
298
|
+
* console.log('Using static API key from resources');
|
|
299
|
+
* }
|
|
300
|
+
*/
|
|
301
|
+
getDynamicStreamVideoApikey(): Promise<DynamicApiKeyResponse>;
|
|
266
302
|
}
|
|
267
303
|
/**
|
|
268
304
|
* @interface IncomingCallPayload
|
|
@@ -278,4 +314,6 @@ export interface IncomingCallPayload {
|
|
|
278
314
|
type: 'incoming';
|
|
279
315
|
/** Information about the caller */
|
|
280
316
|
caller?: CallMember;
|
|
317
|
+
/** Custom data to be passed to the call */
|
|
318
|
+
custom?: Record<string, string | boolean | number | null | Record<string, string | boolean | number | null> | string[] | boolean[] | number[]>;
|
|
281
319
|
}
|