1pub mod channel_view;
2pub mod chat_panel;
3pub mod collab_panel;
4mod collab_titlebar_item;
5mod contact_notification;
6mod face_pile;
7mod incoming_call_notification;
8mod notifications;
9mod panel_settings;
10mod project_shared_notification;
11mod sharing_status_indicator;
12
13use call::{ActiveCall, Room};
14use gpui::{
15 actions,
16 geometry::{
17 rect::RectF,
18 vector::{vec2f, Vector2F},
19 },
20 platform::{Screen, WindowBounds, WindowKind, WindowOptions},
21 AppContext, Task,
22};
23use std::{rc::Rc, sync::Arc};
24use util::ResultExt;
25use workspace::AppState;
26
27pub use collab_titlebar_item::CollabTitlebarItem;
28pub use panel_settings::{ChatPanelSettings, CollaborationPanelSettings};
29
30actions!(
31 collab,
32 [ToggleScreenSharing, ToggleMute, ToggleDeafen, LeaveCall]
33);
34
35pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
36 settings::register::<CollaborationPanelSettings>(cx);
37 settings::register::<ChatPanelSettings>(cx);
38
39 vcs_menu::init(cx);
40 collab_titlebar_item::init(cx);
41 collab_panel::init(cx);
42 chat_panel::init(cx);
43 incoming_call_notification::init(&app_state, cx);
44 project_shared_notification::init(&app_state, cx);
45 sharing_status_indicator::init(cx);
46
47 cx.add_global_action(toggle_screen_sharing);
48 cx.add_global_action(toggle_mute);
49 cx.add_global_action(toggle_deafen);
50}
51
52pub fn toggle_screen_sharing(_: &ToggleScreenSharing, cx: &mut AppContext) {
53 let call = ActiveCall::global(cx).read(cx);
54 if let Some(room) = call.room().cloned() {
55 let client = call.client();
56 let toggle_screen_sharing = room.update(cx, |room, cx| {
57 if room.is_screen_sharing() {
58 ActiveCall::report_call_event_for_room(
59 "disable screen share",
60 Some(room.id()),
61 room.channel_id(),
62 &client,
63 cx,
64 );
65 Task::ready(room.unshare_screen(cx))
66 } else {
67 ActiveCall::report_call_event_for_room(
68 "enable screen share",
69 Some(room.id()),
70 room.channel_id(),
71 &client,
72 cx,
73 );
74 room.share_screen(cx)
75 }
76 });
77 toggle_screen_sharing.detach_and_log_err(cx);
78 }
79}
80
81pub fn toggle_mute(_: &ToggleMute, cx: &mut AppContext) {
82 let call = ActiveCall::global(cx).read(cx);
83 if let Some(room) = call.room().cloned() {
84 let client = call.client();
85 room.update(cx, |room, cx| {
86 if room.is_muted(cx) {
87 ActiveCall::report_call_event_for_room(
88 "enable microphone",
89 Some(room.id()),
90 room.channel_id(),
91 &client,
92 cx,
93 );
94 } else {
95 ActiveCall::report_call_event_for_room(
96 "disable microphone",
97 Some(room.id()),
98 room.channel_id(),
99 &client,
100 cx,
101 );
102 }
103 room.toggle_mute(cx)
104 })
105 .map(|task| task.detach_and_log_err(cx))
106 .log_err();
107 }
108}
109
110pub fn toggle_deafen(_: &ToggleDeafen, cx: &mut AppContext) {
111 if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() {
112 room.update(cx, Room::toggle_deafen)
113 .map(|task| task.detach_and_log_err(cx))
114 .log_err();
115 }
116}
117
118fn notification_window_options(
119 screen: Rc<dyn Screen>,
120 window_size: Vector2F,
121) -> WindowOptions<'static> {
122 const NOTIFICATION_PADDING: f32 = 16.;
123
124 let screen_bounds = screen.content_bounds();
125 WindowOptions {
126 bounds: WindowBounds::Fixed(RectF::new(
127 screen_bounds.upper_right()
128 + vec2f(
129 -NOTIFICATION_PADDING - window_size.x(),
130 NOTIFICATION_PADDING,
131 ),
132 window_size,
133 )),
134 titlebar: None,
135 center: false,
136 focus: false,
137 show: true,
138 kind: WindowKind::PopUp,
139 is_movable: false,
140 screen: Some(screen),
141 }
142}