1use anyhow::{anyhow, Result};
2use client::ParticipantIndex;
3use client::{proto, User};
4use collections::HashMap;
5use gpui::WeakModelHandle;
6pub use live_kit_client::Frame;
7use live_kit_client::RemoteAudioTrack;
8use project::Project;
9use std::{fmt, sync::Arc};
10
11#[derive(Copy, Clone, Debug, Eq, PartialEq)]
12pub enum ParticipantLocation {
13 SharedProject { project_id: u64 },
14 UnsharedProject,
15 External,
16}
17
18impl ParticipantLocation {
19 pub fn from_proto(location: Option<proto::ParticipantLocation>) -> Result<Self> {
20 match location.and_then(|l| l.variant) {
21 Some(proto::participant_location::Variant::SharedProject(project)) => {
22 Ok(Self::SharedProject {
23 project_id: project.id,
24 })
25 }
26 Some(proto::participant_location::Variant::UnsharedProject(_)) => {
27 Ok(Self::UnsharedProject)
28 }
29 Some(proto::participant_location::Variant::External(_)) => Ok(Self::External),
30 None => Err(anyhow!("participant location was not provided")),
31 }
32 }
33}
34
35#[derive(Clone, Default)]
36pub struct LocalParticipant {
37 pub projects: Vec<proto::ParticipantProject>,
38 pub active_project: Option<WeakModelHandle<Project>>,
39}
40
41#[derive(Clone, Debug)]
42pub struct RemoteParticipant {
43 pub user: Arc<User>,
44 pub peer_id: proto::PeerId,
45 pub projects: Vec<proto::ParticipantProject>,
46 pub location: ParticipantLocation,
47 pub participant_index: ParticipantIndex,
48 pub muted: bool,
49 pub speaking: bool,
50 pub video_tracks: HashMap<live_kit_client::Sid, Arc<RemoteVideoTrack>>,
51 pub audio_tracks: HashMap<live_kit_client::Sid, Arc<RemoteAudioTrack>>,
52}
53
54#[derive(Clone)]
55pub struct RemoteVideoTrack {
56 pub(crate) live_kit_track: Arc<live_kit_client::RemoteVideoTrack>,
57}
58
59impl fmt::Debug for RemoteVideoTrack {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 f.debug_struct("RemoteVideoTrack").finish()
62 }
63}
64
65impl RemoteVideoTrack {
66 pub fn frames(&self) -> async_broadcast::Receiver<Frame> {
67 self.live_kit_track.frames()
68 }
69}