@@ -43,8 +43,18 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
4343 public var audioLevel : Float
4444 /// List of the last 10 audio levels.
4545 public var audioLevels : [ Float ]
46+ /// Pinning metadata used to keep this participant visible across layouts.
47+ ///
48+ /// If set, the participant is considered pinned either locally or remotely.
49+ /// SDK integrators can use this to reflect UI state (e.g., always visible).
4650 public var pin : PinInfo ?
4751
52+ /// The set of media track types currently paused for this participant.
53+ ///
54+ /// This is used to control bandwidth or presentation. SDK integrators can
55+ /// rely on it to know when a participant's track has been paused remotely.
56+ public var pausedTracks : Set < TrackType >
57+
4858 /// The user's id. This is not necessarily unique, since a user can join from multiple devices.
4959 public var userId : String {
5060 user. id
@@ -81,7 +91,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
8191 joinedAt: Date ,
8292 audioLevel: Float ,
8393 audioLevels: [ Float ] ,
84- pin: PinInfo ?
94+ pin: PinInfo ? ,
95+ pausedTracks: Set < TrackType >
8596 ) {
8697 user = User (
8798 id: userId,
@@ -106,6 +117,7 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
106117 self . audioLevel = audioLevel
107118 self . audioLevels = audioLevels
108119 self . pin = pin
120+ self . pausedTracks = pausedTracks
109121 }
110122
111123 public static func == ( lhs: CallParticipant , rhs: CallParticipant ) -> Bool {
@@ -127,7 +139,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
127139 lhs. audioLevels == rhs. audioLevels &&
128140 lhs. pin == rhs. pin &&
129141 lhs. track === rhs. track &&
130- lhs. screenshareTrack === rhs. screenshareTrack
142+ lhs. screenshareTrack === rhs. screenshareTrack &&
143+ lhs. pausedTracks == rhs. pausedTracks
131144 }
132145
133146 public var isPinned : Bool {
@@ -141,7 +154,7 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
141154
142155 /// Determines whether the track of the participant should be displayed.
143156 public var shouldDisplayTrack : Bool {
144- hasVideo && showTrack && track != nil
157+ hasVideo && showTrack && track != nil && pausedTracks . contains ( . video ) == false
145158 }
146159
147160 public func withUpdated( trackSize: CGSize ) -> CallParticipant {
@@ -166,7 +179,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
166179 joinedAt: joinedAt,
167180 audioLevel: audioLevel,
168181 audioLevels: audioLevels,
169- pin: pin
182+ pin: pin,
183+ pausedTracks: pausedTracks
170184 )
171185 }
172186
@@ -192,7 +206,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
192206 joinedAt: joinedAt,
193207 audioLevel: audioLevel,
194208 audioLevels: audioLevels,
195- pin: pin
209+ pin: pin,
210+ pausedTracks: pausedTracks
196211 )
197212 }
198213
@@ -218,7 +233,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
218233 joinedAt: joinedAt,
219234 audioLevel: audioLevel,
220235 audioLevels: audioLevels,
221- pin: pin
236+ pin: pin,
237+ pausedTracks: pausedTracks
222238 )
223239 }
224240
@@ -244,7 +260,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
244260 joinedAt: joinedAt,
245261 audioLevel: audioLevel,
246262 audioLevels: audioLevels,
247- pin: pin
263+ pin: pin,
264+ pausedTracks: pausedTracks
248265 )
249266 }
250267
@@ -270,7 +287,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
270287 joinedAt: joinedAt,
271288 audioLevel: audioLevel,
272289 audioLevels: audioLevels,
273- pin: pin
290+ pin: pin,
291+ pausedTracks: pausedTracks
274292 )
275293 }
276294
@@ -296,7 +314,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
296314 joinedAt: joinedAt,
297315 audioLevel: audioLevel,
298316 audioLevels: audioLevels,
299- pin: pin
317+ pin: pin,
318+ pausedTracks: pausedTracks
300319 )
301320 }
302321
@@ -322,7 +341,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
322341 joinedAt: joinedAt,
323342 audioLevel: audioLevel,
324343 audioLevels: audioLevels,
325- pin: pin
344+ pin: pin,
345+ pausedTracks: pausedTracks
326346 )
327347 }
328348
@@ -348,7 +368,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
348368 joinedAt: joinedAt,
349369 audioLevel: audioLevel,
350370 audioLevels: audioLevels,
351- pin: pin
371+ pin: pin,
372+ pausedTracks: pausedTracks
352373 )
353374 }
354375
@@ -383,7 +404,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
383404 joinedAt: joinedAt,
384405 audioLevel: audioLevel,
385406 audioLevels: levels,
386- pin: pin
407+ pin: pin,
408+ pausedTracks: pausedTracks
387409 )
388410 }
389411
@@ -409,7 +431,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
409431 joinedAt: joinedAt,
410432 audioLevel: audioLevel,
411433 audioLevels: audioLevels,
412- pin: pin
434+ pin: pin,
435+ pausedTracks: pausedTracks
413436 )
414437 }
415438
@@ -435,7 +458,8 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
435458 joinedAt: joinedAt,
436459 audioLevel: audioLevel,
437460 audioLevels: audioLevels,
438- pin: pin
461+ pin: pin,
462+ pausedTracks: pausedTracks
439463 )
440464 }
441465
@@ -461,7 +485,66 @@ public struct CallParticipant: Identifiable, Sendable, Hashable {
461485 joinedAt: joinedAt,
462486 audioLevel: audioLevel,
463487 audioLevels: audioLevels,
464- pin: pin
488+ pin: pin,
489+ pausedTracks: pausedTracks
490+ )
491+ }
492+
493+ public func withPausedTrack( _ trackType: TrackType ) -> CallParticipant {
494+ var updatedPausedTracks = pausedTracks
495+ updatedPausedTracks. insert ( trackType)
496+ return CallParticipant (
497+ id: id,
498+ userId: userId,
499+ roles: roles,
500+ name: name,
501+ profileImageURL: profileImageURL,
502+ trackLookupPrefix: trackLookupPrefix,
503+ hasVideo: hasVideo,
504+ hasAudio: hasAudio,
505+ isScreenSharing: isScreensharing,
506+ showTrack: showTrack,
507+ track: track,
508+ trackSize: trackSize,
509+ screenshareTrack: screenshareTrack,
510+ isSpeaking: isSpeaking,
511+ isDominantSpeaker: isDominantSpeaker,
512+ sessionId: sessionId,
513+ connectionQuality: connectionQuality,
514+ joinedAt: joinedAt,
515+ audioLevel: audioLevel,
516+ audioLevels: audioLevels,
517+ pin: pin,
518+ pausedTracks: updatedPausedTracks
519+ )
520+ }
521+
522+ public func withUnpausedTrack( _ trackType: TrackType ) -> CallParticipant {
523+ var updatedPausedTracks = pausedTracks
524+ updatedPausedTracks. remove ( trackType)
525+ return CallParticipant (
526+ id: id,
527+ userId: userId,
528+ roles: roles,
529+ name: name,
530+ profileImageURL: profileImageURL,
531+ trackLookupPrefix: trackLookupPrefix,
532+ hasVideo: hasVideo,
533+ hasAudio: hasAudio,
534+ isScreenSharing: isScreensharing,
535+ showTrack: showTrack,
536+ track: track,
537+ trackSize: trackSize,
538+ screenshareTrack: screenshareTrack,
539+ isSpeaking: isSpeaking,
540+ isDominantSpeaker: isDominantSpeaker,
541+ sessionId: sessionId,
542+ connectionQuality: connectionQuality,
543+ joinedAt: joinedAt,
544+ audioLevel: audioLevel,
545+ audioLevels: audioLevels,
546+ pin: pin,
547+ pausedTracks: updatedPausedTracks
465548 )
466549 }
467550}
0 commit comments