1use gpui2::{Hsla, ViewContext};
2
3use crate::theme;
4
5#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
6pub enum PlayerStatus {
7 #[default]
8 Offline,
9 Online,
10 InCall,
11 Away,
12 DoNotDisturb,
13 Invisible,
14}
15
16#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
17pub enum MicStatus {
18 Muted,
19 #[default]
20 Unmuted,
21}
22
23#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
24pub enum VideoStatus {
25 On,
26 #[default]
27 Off,
28}
29
30#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
31pub enum ScreenShareStatus {
32 Shared,
33 #[default]
34 NotShared,
35}
36
37#[derive(Clone)]
38pub struct PlayerCallStatus {
39 pub mic_status: MicStatus,
40 /// Indicates if the player is currently speaking
41 /// And the intensity of the volume coming through
42 ///
43 /// 0.0 - 1.0
44 pub voice_activity: f32,
45 pub video_status: VideoStatus,
46 pub screen_share_status: ScreenShareStatus,
47 pub in_current_project: bool,
48 pub disconnected: bool,
49 pub following: Option<Vec<Player>>,
50 pub followers: Option<Vec<Player>>,
51}
52
53impl PlayerCallStatus {
54 pub fn new() -> Self {
55 Self {
56 mic_status: MicStatus::default(),
57 voice_activity: 0.,
58 video_status: VideoStatus::default(),
59 screen_share_status: ScreenShareStatus::default(),
60 in_current_project: true,
61 disconnected: false,
62 following: None,
63 followers: None,
64 }
65 }
66}
67
68#[derive(Clone)]
69pub struct Player {
70 index: usize,
71 avatar_src: String,
72 username: String,
73 status: PlayerStatus,
74}
75
76pub struct PlayerWithCallStatus {
77 player: Player,
78 call_status: PlayerCallStatus,
79}
80
81impl PlayerWithCallStatus {
82 pub fn new(player: Player, call_status: PlayerCallStatus) -> Self {
83 Self {
84 player,
85 call_status,
86 }
87 }
88
89 pub fn get_player(&self) -> &Player {
90 &self.player
91 }
92
93 pub fn get_call_status(&self) -> &PlayerCallStatus {
94 &self.call_status
95 }
96}
97
98impl Player {
99 pub fn new(index: usize, avatar_src: String, username: String) -> Self {
100 Self {
101 index,
102 avatar_src,
103 username,
104 status: Default::default(),
105 }
106 }
107
108 pub fn set_status(mut self, status: PlayerStatus) -> Self {
109 self.status = status;
110 self
111 }
112
113 pub fn cursor_color<V>(&self, cx: &mut ViewContext<V>) -> Hsla {
114 let theme = theme(cx);
115 let index = self.index % 8;
116 theme.players[self.index].cursor
117 }
118
119 pub fn selection_color<V>(&self, cx: &mut ViewContext<V>) -> Hsla {
120 let theme = theme(cx);
121 let index = self.index % 8;
122 theme.players[self.index].selection
123 }
124
125 pub fn avatar_src(&self) -> &str {
126 &self.avatar_src
127 }
128
129 pub fn index(&self) -> usize {
130 self.index
131 }
132}