@capgo/capacitor-stream-call 0.0.87 → 0.0.89

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 CHANGED
@@ -254,6 +254,7 @@ export class CallService {
254
254
  * [`getCallInfo(...)`](#getcallinfo)
255
255
  * [`setDynamicStreamVideoApikey(...)`](#setdynamicstreamvideoapikey)
256
256
  * [`getDynamicStreamVideoApikey()`](#getdynamicstreamvideoapikey)
257
+ * [`getCurrentUser()`](#getcurrentuser)
257
258
  * [Interfaces](#interfaces)
258
259
  * [Type Aliases](#type-aliases)
259
260
  * [Enums](#enums)
@@ -538,6 +539,19 @@ Get the currently set dynamic Stream Video API key
538
539
  --------------------
539
540
 
540
541
 
542
+ ### getCurrentUser()
543
+
544
+ ```typescript
545
+ getCurrentUser() => Promise<CurrentUserResponse>
546
+ ```
547
+
548
+ Get the current user's information
549
+
550
+ **Returns:** <code>Promise&lt;<a href="#currentuserresponse">CurrentUserResponse</a>&gt;</code>
551
+
552
+ --------------------
553
+
554
+
541
555
  ### Interfaces
542
556
 
543
557
 
@@ -819,6 +833,16 @@ The JSON representation for <a href="#listvalue">`ListValue`</a> is JSON array.
819
833
  | **`hasDynamicKey`** | <code>boolean</code> | Whether a dynamic key is currently set |
820
834
 
821
835
 
836
+ #### CurrentUserResponse
837
+
838
+ | Prop | Type | Description |
839
+ | ---------------- | -------------------- | --------------------------------------- |
840
+ | **`userId`** | <code>string</code> | User ID of the current user |
841
+ | **`name`** | <code>string</code> | Display name of the current user |
842
+ | **`imageURL`** | <code>string</code> | Avatar URL of the current user |
843
+ | **`isLoggedIn`** | <code>boolean</code> | Whether the user is currently logged in |
844
+
845
+
822
846
  ### Type Aliases
823
847
 
824
848
 
@@ -73,6 +73,8 @@ dependencies {
73
73
  implementation "androidx.compose.foundation:foundation:$compose_version"
74
74
  implementation "androidx.compose.runtime:runtime:$compose_version"
75
75
  implementation "androidx.compose.material3:material3:1.3.2"
76
+ implementation 'androidx.media:media:1.7.0'
77
+
76
78
 
77
79
  // Stream dependencies
78
80
  implementation("io.getstream:stream-video-android-ui-compose:1.9.2")
@@ -0,0 +1,161 @@
1
+ package ee.forgr.capacitor.streamcall
2
+
3
+ import android.app.Application
4
+ import android.app.PendingIntent
5
+ import android.content.ComponentName
6
+ import android.content.Intent
7
+ import android.content.pm.ResolveInfo
8
+ import io.getstream.log.taggedLogger
9
+ import io.getstream.video.android.core.notifications.NotificationHandler
10
+ import io.getstream.video.android.core.notifications.StreamIntentResolver
11
+ import io.getstream.video.android.model.StreamCallId
12
+
13
+ class CustomStreamIntentResolver(private val context: Application) : StreamIntentResolver {
14
+
15
+ private val logger by taggedLogger("CustomIntentResolver")
16
+ private val PENDING_INTENT_FLAG = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
17
+
18
+ override fun searchIncomingCallPendingIntent(callId: StreamCallId, notificationId: Int): PendingIntent? {
19
+ val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)?.apply {
20
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP
21
+ putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, callId)
22
+ action = "io.getstream.video.android.action.INCOMING_CALL"
23
+
24
+ }
25
+
26
+ return PendingIntent.getActivity(
27
+ context,
28
+ callId.cid.hashCode(),
29
+ launchIntent,
30
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
31
+ )
32
+ }
33
+
34
+ override fun searchOutgoingCallPendingIntent(callId: StreamCallId, notificationId: Int): PendingIntent? {
35
+ // For outgoing calls, create a specific intent that only opens webview when user taps
36
+ val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)?.apply {
37
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
38
+ putExtra("callCid", callId.cid)
39
+ putExtra("action", "outgoing_call_tap") // Different action to distinguish from automatic events
40
+ putExtra("openWebview", true)
41
+ putExtra("fromNotification", true)
42
+ putExtra("userTapped", true) // Explicitly mark this as user-initiated
43
+ action = "ee.forgr.capacitor.streamcall.OUTGOING_CALL_TAP.${callId.cid}"
44
+ }
45
+
46
+ return PendingIntent.getActivity(
47
+ context,
48
+ callId.cid.hashCode(),
49
+ launchIntent,
50
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
51
+ )
52
+ }
53
+
54
+ override fun searchNotificationCallPendingIntent(callId: StreamCallId, notificationId: Int): PendingIntent? =
55
+ searchActivityPendingIntent(Intent(NotificationHandler.ACTION_NOTIFICATION), callId, notificationId)
56
+
57
+ override fun searchMissedCallPendingIntent(callId: StreamCallId, notificationId: Int): PendingIntent? =
58
+ searchActivityPendingIntent(Intent(NotificationHandler.ACTION_MISSED_CALL), callId, notificationId)
59
+
60
+ override fun getDefaultPendingIntent(): PendingIntent {
61
+ val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)
62
+ ?: Intent(Intent.ACTION_MAIN).apply {
63
+ setPackage(context.packageName)
64
+ addCategory(Intent.CATEGORY_LAUNCHER)
65
+ }
66
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
67
+ return PendingIntent.getActivity(
68
+ context,
69
+ 0,
70
+ intent,
71
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
72
+ )
73
+ }
74
+
75
+ override fun searchLiveCallPendingIntent(callId: StreamCallId, notificationId: Int): PendingIntent? =
76
+ searchActivityPendingIntent(Intent(NotificationHandler.ACTION_LIVE_CALL), callId, notificationId)
77
+
78
+ override fun searchAcceptCallPendingIntent(callId: StreamCallId, notificationId: Int): PendingIntent? {
79
+ val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)?.apply {
80
+ action = NotificationHandler.ACTION_ACCEPT_CALL
81
+ putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, callId)
82
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
83
+ }
84
+
85
+ return PendingIntent.getActivity(
86
+ context,
87
+ callId.cid.hashCode() + 10,
88
+ launchIntent,
89
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
90
+ )
91
+ }
92
+
93
+ override fun searchRejectCallPendingIntent(callId: StreamCallId): PendingIntent? =
94
+ searchBroadcastPendingIntent(Intent(NotificationHandler.ACTION_REJECT_CALL), callId)
95
+
96
+ override fun searchEndCallPendingIntent(callId: StreamCallId): PendingIntent? {
97
+ val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)?.apply {
98
+ action = NotificationHandler.ACTION_LEAVE_CALL
99
+ putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, callId)
100
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
101
+ }
102
+
103
+ return PendingIntent.getActivity(
104
+ context,
105
+ callId.cid.hashCode() + 30,
106
+ launchIntent,
107
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
108
+ )
109
+ }
110
+
111
+ override fun searchOngoingCallPendingIntent(callId: StreamCallId, notificationId: Int): PendingIntent? {
112
+ val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)?.apply {
113
+ action = NotificationHandler.ACTION_ONGOING_CALL
114
+ putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, callId)
115
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
116
+ }
117
+
118
+ return PendingIntent.getActivity(
119
+ context,
120
+ callId.cid.hashCode() + 20,
121
+ launchIntent,
122
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
123
+ )
124
+ }
125
+
126
+ private fun searchBroadcastPendingIntent(baseIntent: Intent, callId: StreamCallId): PendingIntent? =
127
+ searchResolveInfo { context.packageManager.queryBroadcastReceivers(baseIntent, 0) }?.let {
128
+ getBroadcastForIntent(baseIntent, it, callId)
129
+ }
130
+
131
+ private fun searchActivityPendingIntent(baseIntent: Intent, callId: StreamCallId, notificationId: Int): PendingIntent? =
132
+ searchResolveInfo { context.packageManager.queryIntentActivities(baseIntent, 0) }?.let {
133
+ getActivityForIntent(baseIntent, it, callId, notificationId)
134
+ }
135
+
136
+ private fun searchResolveInfo(availableComponents: () -> List<ResolveInfo>): ResolveInfo? =
137
+ availableComponents()
138
+ .filter { it.activityInfo.packageName == context.packageName }
139
+ .maxByOrNull { it.priority }
140
+
141
+ private fun getActivityForIntent(baseIntent: Intent, resolveInfo: ResolveInfo, callId: StreamCallId, notificationId: Int, flags: Int = PENDING_INTENT_FLAG): PendingIntent {
142
+ return PendingIntent.getActivity(
143
+ context,
144
+ notificationId,
145
+ buildComponentIntent(baseIntent, resolveInfo, callId),
146
+ flags
147
+ )
148
+ }
149
+
150
+ private fun getBroadcastForIntent(baseIntent: Intent, resolveInfo: ResolveInfo, callId: StreamCallId, flags: Int = PENDING_INTENT_FLAG): PendingIntent {
151
+ return PendingIntent.getBroadcast(context, 0, buildComponentIntent(baseIntent, resolveInfo, callId), flags)
152
+ }
153
+
154
+ private fun buildComponentIntent(baseIntent: Intent, resolveInfo: ResolveInfo, callId: StreamCallId): Intent {
155
+ return Intent(baseIntent).apply {
156
+ component = ComponentName(resolveInfo.activityInfo.applicationInfo.packageName, resolveInfo.activityInfo.name)
157
+ putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, callId)
158
+ putExtra(NotificationHandler.INTENT_EXTRA_NOTIFICATION_ID, NotificationHandler.INCOMING_CALL_NOTIFICATION_ID)
159
+ }
160
+ }
161
+ }
@@ -73,6 +73,10 @@ import io.getstream.video.android.core.events.ParticipantLeftEvent
73
73
  import io.getstream.video.android.core.internal.InternalStreamVideoApi
74
74
  import io.getstream.video.android.core.notifications.NotificationConfig
75
75
  import io.getstream.video.android.core.notifications.NotificationHandler
76
+ import io.getstream.video.android.core.notifications.handlers.CompatibilityStreamNotificationHandler
77
+ import io.getstream.video.android.core.notifications.handlers.StreamNotificationBuilderInterceptors
78
+ import androidx.core.app.NotificationCompat
79
+ import android.app.PendingIntent
76
80
  import io.getstream.video.android.core.sounds.RingingConfig
77
81
  import io.getstream.video.android.core.sounds.toSounds
78
82
  import io.getstream.video.android.model.Device
@@ -196,16 +200,20 @@ class StreamCallPlugin : Plugin() {
196
200
  }
197
201
 
198
202
  override fun load() {
203
+ Log.d("StreamCallPlugin", "Plugin load() called")
199
204
  try {
200
205
  val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
201
206
  if (packageInfo.firstInstallTime == packageInfo.lastUpdateTime) {
202
207
  Log.d("StreamCallPlugin", "Fresh install detected, clearing user credentials.")
203
208
  SecureUserRepository.getInstance(context).removeCurrentUser()
209
+ } else {
210
+ Log.d("StreamCallPlugin", "App update or existing installation detected")
204
211
  }
205
212
  } catch (e: Exception) {
206
213
  Log.e("StreamCallPlugin", "Error checking for fresh install", e)
207
214
  }
208
215
  // general init
216
+ Log.d("StreamCallPlugin", "Calling initializeStreamVideo() from load()")
209
217
  initializeStreamVideo()
210
218
  setupViews()
211
219
  super.load()
@@ -316,6 +324,12 @@ class StreamCallPlugin : Plugin() {
316
324
  Log.e("StreamCallPlugin", "handleOnNewIntent: ACCEPT_CALL - Call object is null for cid: $cid")
317
325
  }
318
326
  }
327
+ } else if (action === NotificationHandler.ACTION_LEAVE_CALL) {
328
+ Log.d("StreamCallPlugin", "handleOnNewIntent: Matched LEAVE_CALL action")
329
+ kotlinx.coroutines.GlobalScope.launch {
330
+ val success = _endCall()
331
+ Log.d("StreamCallPlugin", "handleOnNewIntent: LEAVE_CALL - End call result: $success")
332
+ }
319
333
  }
320
334
  // Log the intent information
321
335
  Log.d("StreamCallPlugin", "New Intent - Action: $action")
@@ -567,47 +581,6 @@ class StreamCallPlugin : Plugin() {
567
581
  // unsafe cast, add better handling
568
582
  val application = contextToUse.applicationContext as Application
569
583
  Log.d("StreamCallPlugin", "No existing StreamVideo singleton client, creating new one")
570
- val notificationHandler = CustomNotificationHandler(
571
- application = application,
572
- endCall = { callId ->
573
- val activeCall = streamVideoClient?.call(callId.type, callId.id)
574
-
575
- kotlinx.coroutines.GlobalScope.launch {
576
- try {
577
- Log.i(
578
- "StreamCallPlugin",
579
- "Attempt to endCallRaw, activeCall == null: ${activeCall == null}",
580
- )
581
- activeCall?.let { endCallRaw(it) }
582
- } catch (e: Exception) {
583
- Log.e(
584
- "StreamCallPlugin",
585
- "Error ending after missed call notif action",
586
- e
587
- )
588
- }
589
- }
590
- },
591
- incomingCall = {
592
- if (this.savedContext != null && initializationTime != 0L) {
593
- val contextCreatedAt = initializationTime
594
- val now = System.currentTimeMillis()
595
- val isWithinOneSecond = (now - contextCreatedAt) <= 1000L
596
-
597
- Log.i(
598
- "StreamCallPlugin",
599
- "Time between context creation and activity created (incoming call notif): ${now - contextCreatedAt}"
600
- )
601
- if (isWithinOneSecond && !bootedToHandleCall) {
602
- Log.i(
603
- "StreamCallPlugin",
604
- "Notification incomingCall received less than 1 second after the creation of streamVideoSDK. Booted FOR SURE in order to handle the notification"
605
- )
606
- }
607
- }
608
- }
609
- )
610
-
611
584
  val notificationConfig = NotificationConfig(
612
585
  pushDeviceGenerators = listOf(
613
586
  FirebasePushDeviceGenerator(
@@ -616,7 +589,23 @@ class StreamCallPlugin : Plugin() {
616
589
  )
617
590
  ),
618
591
  requestPermissionOnAppLaunch = { true },
619
- notificationHandler = notificationHandler,
592
+ notificationHandler = CompatibilityStreamNotificationHandler(
593
+ application = application,
594
+ intentResolver = CustomStreamIntentResolver(application),
595
+ initialNotificationBuilderInterceptor = object : StreamNotificationBuilderInterceptors() {
596
+ override fun onBuildIncomingCallNotification(
597
+ builder: NotificationCompat.Builder,
598
+ fullScreenPendingIntent: PendingIntent,
599
+ acceptCallPendingIntent: PendingIntent,
600
+ rejectCallPendingIntent: PendingIntent,
601
+ callerName: String?,
602
+ shouldHaveContentIntent: Boolean
603
+ ): NotificationCompat.Builder {
604
+ return builder.setContentIntent(fullScreenPendingIntent)
605
+ .setFullScreenIntent(fullScreenPendingIntent, true)
606
+ }
607
+ }
608
+ )
620
609
  )
621
610
 
622
611
  val soundsConfig = incomingOnlyRingingConfig()
@@ -1976,28 +1965,41 @@ class StreamCallPlugin : Plugin() {
1976
1965
  }
1977
1966
 
1978
1967
  @OptIn(DelicateCoroutinesApi::class)
1968
+ private suspend fun _endCall(): Boolean {
1969
+ val activeCall = streamVideoClient?.state?.activeCall?.value
1970
+ val ringingCall = streamVideoClient?.state?.ringingCall?.value
1971
+
1972
+ val callToEnd = activeCall ?: ringingCall
1973
+
1974
+ if (callToEnd == null) {
1975
+ Log.w("StreamCallPlugin", "Attempted to end call but no active or ringing call found")
1976
+ return false
1977
+ }
1978
+
1979
+ Log.d("StreamCallPlugin", "Ending call: activeCall=${activeCall?.id}, ringingCall=${ringingCall?.id}, callToEnd=${callToEnd.id}")
1980
+
1981
+ return try {
1982
+ endCallRaw(callToEnd)
1983
+ true
1984
+ } catch (e: Exception) {
1985
+ Log.e("StreamCallPlugin", "Error ending call: ${e.message}", e)
1986
+ false
1987
+ }
1988
+ }
1989
+
1979
1990
  @PluginMethod
1980
1991
  fun endCall(call: PluginCall) {
1981
1992
  try {
1982
- val activeCall = streamVideoClient?.state?.activeCall?.value
1983
- val ringingCall = streamVideoClient?.state?.ringingCall?.value
1984
-
1985
- val callToEnd = activeCall ?: ringingCall
1986
-
1987
- if (callToEnd == null) {
1988
- Log.w("StreamCallPlugin", "Attempted to end call but no active or ringing call found")
1989
- call.reject("No active call to end")
1990
- return
1991
- }
1992
-
1993
- Log.d("StreamCallPlugin", "Ending call: activeCall=${activeCall?.id}, ringingCall=${ringingCall?.id}, callToEnd=${callToEnd.id}")
1994
-
1995
1993
  kotlinx.coroutines.GlobalScope.launch {
1996
1994
  try {
1997
- endCallRaw(callToEnd)
1998
- call.resolve(JSObject().apply {
1999
- put("success", true)
2000
- })
1995
+ val success = _endCall()
1996
+ if (success) {
1997
+ call.resolve(JSObject().apply {
1998
+ put("success", true)
1999
+ })
2000
+ } else {
2001
+ call.reject("No active call to end")
2002
+ }
2001
2003
  } catch (e: Exception) {
2002
2004
  Log.e("StreamCallPlugin", "Error ending call: ${e.message}")
2003
2005
  call.reject("Failed to end call: ${e.message}")
@@ -2501,6 +2503,35 @@ class StreamCallPlugin : Plugin() {
2501
2503
  }
2502
2504
  }
2503
2505
 
2506
+ @PluginMethod
2507
+ fun getCurrentUser(call: PluginCall) {
2508
+ Log.d("StreamCallPlugin", "getCurrentUser called")
2509
+ try {
2510
+ val savedCredentials = SecureUserRepository.getInstance(context).loadCurrentUser()
2511
+ val ret = JSObject()
2512
+
2513
+ if (savedCredentials != null) {
2514
+ Log.d("StreamCallPlugin", "getCurrentUser: Found saved credentials for user: ${savedCredentials.user.id}")
2515
+ ret.put("userId", savedCredentials.user.id)
2516
+ ret.put("name", savedCredentials.user.name ?: "")
2517
+ ret.put("imageURL", savedCredentials.user.image ?: "")
2518
+ ret.put("isLoggedIn", true)
2519
+ } else {
2520
+ Log.d("StreamCallPlugin", "getCurrentUser: No saved credentials found")
2521
+ ret.put("userId", "")
2522
+ ret.put("name", "")
2523
+ ret.put("imageURL", "")
2524
+ ret.put("isLoggedIn", false)
2525
+ }
2526
+
2527
+ Log.d("StreamCallPlugin", "getCurrentUser: Returning ${ret}")
2528
+ call.resolve(ret)
2529
+ } catch (e: Exception) {
2530
+ Log.e("StreamCallPlugin", "getCurrentUser: Failed to get current user", e)
2531
+ call.reject("Failed to get current user", e)
2532
+ }
2533
+ }
2534
+
2504
2535
  companion object {
2505
2536
  @JvmStatic fun preLoadInit(ctx: Context, app: Application) {
2506
2537
  holder ?: run {
@@ -50,6 +50,8 @@ class SecureUserRepository private constructor(context: Context) : UserRepositor
50
50
  }
51
51
 
52
52
  override fun save(user: UserCredentials) {
53
+ android.util.Log.d("SecureUserRepository", "Saving user credentials for: ${user.user.id}")
54
+
53
55
  val customJson = user.user.custom?.let { customMap ->
54
56
  JSONObject().apply {
55
57
  customMap.forEach { (key, value) ->
@@ -70,6 +72,8 @@ class SecureUserRepository private constructor(context: Context) : UserRepositor
70
72
  putString(KEY_USER, userJson.toString())
71
73
  putString(KEY_TOKEN, user.tokenValue)
72
74
  }
75
+
76
+ android.util.Log.d("SecureUserRepository", "User credentials saved successfully for: ${user.user.id}")
73
77
  }
74
78
 
75
79
  override fun save(token: String) {
@@ -77,6 +81,8 @@ class SecureUserRepository private constructor(context: Context) : UserRepositor
77
81
  }
78
82
 
79
83
  override fun loadCurrentUser(): UserCredentials? {
84
+ android.util.Log.d("SecureUserRepository", "Loading current user credentials")
85
+
80
86
  val userJson = sharedPreferences.getString(KEY_USER, null)
81
87
  val token = sharedPreferences.getString(KEY_TOKEN, null)
82
88
 
@@ -91,20 +97,26 @@ class SecureUserRepository private constructor(context: Context) : UserRepositor
91
97
  role = jsonObject.optString("role"),
92
98
  custom = ArrayMap()
93
99
  )
94
- UserCredentials(user, token)
100
+ val credentials = UserCredentials(user, token)
101
+ android.util.Log.d("SecureUserRepository", "Successfully loaded credentials for user: ${user.id}")
102
+ credentials
95
103
  } else {
104
+ android.util.Log.d("SecureUserRepository", "No stored credentials found (userJson: ${userJson != null}, token: ${token != null})")
96
105
  null
97
106
  }
98
107
  } catch (e: Exception) {
108
+ android.util.Log.e("SecureUserRepository", "Error loading user credentials", e)
99
109
  e.printStackTrace()
100
110
  null
101
111
  }
102
112
  }
103
113
 
104
114
  override fun removeCurrentUser() {
115
+ android.util.Log.d("SecureUserRepository", "Removing current user credentials")
105
116
  sharedPreferences.edit {
106
117
  remove(KEY_USER)
107
118
  remove(KEY_TOKEN)
108
119
  }
120
+ android.util.Log.d("SecureUserRepository", "User credentials removed successfully")
109
121
  }
110
- }
122
+ }
package/dist/docs.json CHANGED
@@ -483,6 +483,27 @@
483
483
  "DynamicApiKeyResponse"
484
484
  ],
485
485
  "slug": "getdynamicstreamvideoapikey"
486
+ },
487
+ {
488
+ "name": "getCurrentUser",
489
+ "signature": "() => Promise<CurrentUserResponse>",
490
+ "parameters": [],
491
+ "returns": "Promise<CurrentUserResponse>",
492
+ "tags": [
493
+ {
494
+ "name": "returns",
495
+ "text": "Current user information"
496
+ },
497
+ {
498
+ "name": "example",
499
+ "text": "const currentUser = await StreamCall.getCurrentUser();\nconsole.log(currentUser);"
500
+ }
501
+ ],
502
+ "docs": "Get the current user's information",
503
+ "complexTypes": [
504
+ "CurrentUserResponse"
505
+ ],
506
+ "slug": "getcurrentuser"
486
507
  }
487
508
  ],
488
509
  "properties": []
@@ -1462,6 +1483,68 @@
1462
1483
  "type": "boolean"
1463
1484
  }
1464
1485
  ]
1486
+ },
1487
+ {
1488
+ "name": "CurrentUserResponse",
1489
+ "slug": "currentuserresponse",
1490
+ "docs": "",
1491
+ "tags": [
1492
+ {
1493
+ "text": "CurrentUserResponse",
1494
+ "name": "interface"
1495
+ },
1496
+ {
1497
+ "text": "Response from getCurrentUser containing user information",
1498
+ "name": "description"
1499
+ },
1500
+ {
1501
+ "text": "{string} userId - User ID of the current user",
1502
+ "name": "property"
1503
+ },
1504
+ {
1505
+ "text": "{string} name - Display name of the current user",
1506
+ "name": "property"
1507
+ },
1508
+ {
1509
+ "text": "{string} [imageURL] - Avatar URL of the current user",
1510
+ "name": "property"
1511
+ },
1512
+ {
1513
+ "text": "{boolean} isLoggedIn - Whether the user is currently logged in",
1514
+ "name": "property"
1515
+ }
1516
+ ],
1517
+ "methods": [],
1518
+ "properties": [
1519
+ {
1520
+ "name": "userId",
1521
+ "tags": [],
1522
+ "docs": "User ID of the current user",
1523
+ "complexTypes": [],
1524
+ "type": "string"
1525
+ },
1526
+ {
1527
+ "name": "name",
1528
+ "tags": [],
1529
+ "docs": "Display name of the current user",
1530
+ "complexTypes": [],
1531
+ "type": "string"
1532
+ },
1533
+ {
1534
+ "name": "imageURL",
1535
+ "tags": [],
1536
+ "docs": "Avatar URL of the current user",
1537
+ "complexTypes": [],
1538
+ "type": "string | undefined"
1539
+ },
1540
+ {
1541
+ "name": "isLoggedIn",
1542
+ "tags": [],
1543
+ "docs": "Whether the user is currently logged in",
1544
+ "complexTypes": [],
1545
+ "type": "boolean"
1546
+ }
1547
+ ]
1465
1548
  }
1466
1549
  ],
1467
1550
  "enums": [
@@ -98,6 +98,24 @@ export interface DynamicApiKeyResponse {
98
98
  /** Whether a dynamic key is currently set */
99
99
  hasDynamicKey: boolean;
100
100
  }
101
+ /**
102
+ * @interface CurrentUserResponse
103
+ * @description Response from getCurrentUser containing user information
104
+ * @property {string} userId - User ID of the current user
105
+ * @property {string} name - Display name of the current user
106
+ * @property {string} [imageURL] - Avatar URL of the current user
107
+ * @property {boolean} isLoggedIn - Whether the user is currently logged in
108
+ */
109
+ export interface CurrentUserResponse {
110
+ /** User ID of the current user */
111
+ userId: string;
112
+ /** Display name of the current user */
113
+ name: string;
114
+ /** Avatar URL of the current user */
115
+ imageURL?: string;
116
+ /** Whether the user is currently logged in */
117
+ isLoggedIn: boolean;
118
+ }
101
119
  /**
102
120
  * @interface SuccessResponse
103
121
  * @description Standard response indicating operation success/failure
@@ -299,6 +317,14 @@ export interface StreamCallPlugin {
299
317
  * }
300
318
  */
301
319
  getDynamicStreamVideoApikey(): Promise<DynamicApiKeyResponse>;
320
+ /**
321
+ * Get the current user's information
322
+ * @returns {Promise<CurrentUserResponse>} Current user information
323
+ * @example
324
+ * const currentUser = await StreamCall.getCurrentUser();
325
+ * console.log(currentUser);
326
+ */
327
+ getCurrentUser(): Promise<CurrentUserResponse>;
302
328
  }
303
329
  /**
304
330
  * @interface IncomingCallPayload