player.rs

  1use gpui::{Hsla, ViewContext};
  2
  3use crate::prelude::*;
  4
  5/// Represents a person with a Zed account's public profile.
  6/// All data in this struct should be considered public.
  7pub struct PublicPlayer {
  8    pub username: SharedString,
  9    pub avatar: SharedString,
 10    pub is_contact: bool,
 11}
 12
 13impl PublicPlayer {
 14    pub fn new(username: impl Into<SharedString>, avatar: impl Into<SharedString>) -> Self {
 15        Self {
 16            username: username.into(),
 17            avatar: avatar.into(),
 18            is_contact: false,
 19        }
 20    }
 21}
 22
 23#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
 24pub enum PlayerStatus {
 25    #[default]
 26    Offline,
 27    Online,
 28    InCall,
 29    Away,
 30    DoNotDisturb,
 31    Invisible,
 32}
 33
 34#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
 35pub enum MicStatus {
 36    Muted,
 37    #[default]
 38    Unmuted,
 39}
 40
 41impl MicStatus {
 42    pub fn inverse(&self) -> Self {
 43        match self {
 44            Self::Muted => Self::Unmuted,
 45            Self::Unmuted => Self::Muted,
 46        }
 47    }
 48}
 49
 50#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
 51pub enum VideoStatus {
 52    On,
 53    #[default]
 54    Off,
 55}
 56
 57impl VideoStatus {
 58    pub fn inverse(&self) -> Self {
 59        match self {
 60            Self::On => Self::Off,
 61            Self::Off => Self::On,
 62        }
 63    }
 64}
 65
 66#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
 67pub enum ScreenShareStatus {
 68    Shared,
 69    #[default]
 70    NotShared,
 71}
 72
 73impl ScreenShareStatus {
 74    pub fn inverse(&self) -> Self {
 75        match self {
 76            Self::Shared => Self::NotShared,
 77            Self::NotShared => Self::Shared,
 78        }
 79    }
 80}
 81
 82#[derive(Clone)]
 83pub struct PlayerCallStatus {
 84    pub mic_status: MicStatus,
 85    /// Indicates if the player is currently speaking
 86    /// And the intensity of the volume coming through
 87    ///
 88    /// 0.0 - 1.0
 89    pub voice_activity: f32,
 90    pub video_status: VideoStatus,
 91    pub screen_share_status: ScreenShareStatus,
 92    pub in_current_project: bool,
 93    pub disconnected: bool,
 94    pub following: Option<Vec<Player>>,
 95    pub followers: Option<Vec<Player>>,
 96}
 97
 98impl PlayerCallStatus {
 99    pub fn new() -> Self {
100        Self {
101            mic_status: MicStatus::default(),
102            voice_activity: 0.,
103            video_status: VideoStatus::default(),
104            screen_share_status: ScreenShareStatus::default(),
105            in_current_project: true,
106            disconnected: false,
107            following: None,
108            followers: None,
109        }
110    }
111}
112
113#[derive(PartialEq, Clone)]
114pub struct Player {
115    index: usize,
116    avatar_src: String,
117    username: String,
118    status: PlayerStatus,
119}
120
121#[derive(Clone)]
122pub struct PlayerWithCallStatus {
123    player: Player,
124    call_status: PlayerCallStatus,
125}
126
127impl PlayerWithCallStatus {
128    pub fn new(player: Player, call_status: PlayerCallStatus) -> Self {
129        Self {
130            player,
131            call_status,
132        }
133    }
134
135    pub fn get_player(&self) -> &Player {
136        &self.player
137    }
138
139    pub fn get_call_status(&self) -> &PlayerCallStatus {
140        &self.call_status
141    }
142}
143
144impl Player {
145    pub fn new(index: usize, avatar_src: String, username: String) -> Self {
146        Self {
147            index,
148            avatar_src,
149            username,
150            status: Default::default(),
151        }
152    }
153
154    pub fn set_status(mut self, status: PlayerStatus) -> Self {
155        self.status = status;
156        self
157    }
158
159    pub fn cursor_color<V: 'static>(&self, cx: &mut ViewContext<V>) -> Hsla {
160        cx.theme().styles.player.0[self.index % cx.theme().styles.player.0.len()].cursor
161    }
162
163    pub fn selection_color<V: 'static>(&self, cx: &mut ViewContext<V>) -> Hsla {
164        cx.theme().styles.player.0[self.index % cx.theme().styles.player.0.len()].selection
165    }
166
167    pub fn avatar_src(&self) -> &str {
168        &self.avatar_src
169    }
170
171    pub fn index(&self) -> usize {
172        self.index
173    }
174}