1use crate::{
2 AudioStream, LocalAudioTrack, LocalTrackPublication, LocalVideoTrack, Participant,
3 ParticipantIdentity, RemoteTrack, RemoteTrackPublication, TrackSid,
4 test::{Room, WeakRoom},
5};
6use anyhow::Result;
7use collections::HashMap;
8use gpui::{
9 AsyncApp, DevicePixels, ScreenCaptureSource, ScreenCaptureStream, SourceMetadata, size,
10};
11
12#[derive(Clone, Debug)]
13pub struct LocalParticipant {
14 pub(crate) identity: ParticipantIdentity,
15 pub(crate) room: Room,
16}
17
18#[derive(Clone, Debug)]
19pub struct RemoteParticipant {
20 pub(crate) identity: ParticipantIdentity,
21 pub(crate) room: WeakRoom,
22}
23
24impl Participant {
25 pub fn identity(&self) -> ParticipantIdentity {
26 match self {
27 Participant::Local(participant) => participant.identity.clone(),
28 Participant::Remote(participant) => participant.identity.clone(),
29 }
30 }
31}
32
33impl LocalParticipant {
34 pub async fn unpublish_track(&self, track: TrackSid, _cx: &AsyncApp) -> Result<()> {
35 self.room
36 .test_server()
37 .unpublish_track(self.room.token(), &track)
38 .await
39 }
40
41 pub(crate) async fn publish_microphone_track(
42 &self,
43 _cx: &AsyncApp,
44 ) -> Result<(LocalTrackPublication, AudioStream)> {
45 let this = self.clone();
46 let server = this.room.test_server();
47 let sid = server
48 .publish_audio_track(this.room.token(), &LocalAudioTrack {})
49 .await?;
50
51 Ok((
52 LocalTrackPublication {
53 room: self.room.downgrade(),
54 sid,
55 },
56 AudioStream {},
57 ))
58 }
59
60 pub async fn publish_screenshare_track(
61 &self,
62 _source: &dyn ScreenCaptureSource,
63 _cx: &mut AsyncApp,
64 ) -> Result<(LocalTrackPublication, Box<dyn ScreenCaptureStream>)> {
65 let this = self.clone();
66 let server = this.room.test_server();
67 let sid = server
68 .publish_video_track(this.room.token(), LocalVideoTrack {})
69 .await?;
70 Ok((
71 LocalTrackPublication {
72 room: self.room.downgrade(),
73 sid,
74 },
75 Box::new(TestScreenCaptureStream {}),
76 ))
77 }
78}
79
80impl RemoteParticipant {
81 pub fn track_publications(&self) -> HashMap<TrackSid, RemoteTrackPublication> {
82 if let Some(room) = self.room.upgrade() {
83 let server = room.test_server();
84 let audio = server
85 .audio_tracks(room.token())
86 .unwrap()
87 .into_iter()
88 .filter(|track| track.publisher_id() == self.identity)
89 .map(|track| {
90 (
91 track.sid(),
92 RemoteTrackPublication {
93 sid: track.sid(),
94 room: self.room.clone(),
95 track: RemoteTrack::Audio(track),
96 },
97 )
98 });
99 let video = server
100 .video_tracks(room.token())
101 .unwrap()
102 .into_iter()
103 .filter(|track| track.publisher_id() == self.identity)
104 .map(|track| {
105 (
106 track.sid(),
107 RemoteTrackPublication {
108 sid: track.sid(),
109 room: self.room.clone(),
110 track: RemoteTrack::Video(track),
111 },
112 )
113 });
114 audio.chain(video).collect()
115 } else {
116 HashMap::default()
117 }
118 }
119
120 pub fn identity(&self) -> ParticipantIdentity {
121 self.identity.clone()
122 }
123}
124
125struct TestScreenCaptureStream;
126
127impl ScreenCaptureStream for TestScreenCaptureStream {
128 fn metadata(&self) -> Result<SourceMetadata> {
129 Ok(SourceMetadata {
130 id: 0,
131 is_main: None,
132 label: None,
133 resolution: size(DevicePixels(1), DevicePixels(1)),
134 })
135 }
136}