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;
10pub mod project_shared_notification;
11mod sharing_status_indicator;
12
13use call::{report_call_event_for_room, 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 report_call_event_for_room(
59 "disable screen share",
60 room.id(),
61 room.channel_id(),
62 &client,
63 cx,
64 );
65 Task::ready(room.unshare_screen(cx))
66 } else {
67 report_call_event_for_room(
68 "enable screen share",
69 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 let operation = if room.is_muted(cx) {
87 "enable microphone"
88 } else {
89 "disable microphone"
90 };
91 report_call_event_for_room(operation, room.id(), room.channel_id(), &client, cx);
92
93 room.toggle_mute(cx)
94 })
95 .map(|task| task.detach_and_log_err(cx))
96 .log_err();
97 }
98}
99
100pub fn toggle_deafen(_: &ToggleDeafen, cx: &mut AppContext) {
101 if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() {
102 room.update(cx, Room::toggle_deafen)
103 .map(|task| task.detach_and_log_err(cx))
104 .log_err();
105 }
106}
107
108fn notification_window_options(
109 screen: Rc<dyn Screen>,
110 window_size: Vector2F,
111) -> WindowOptions<'static> {
112 const NOTIFICATION_PADDING: f32 = 16.;
113
114 let screen_bounds = screen.content_bounds();
115 WindowOptions {
116 bounds: WindowBounds::Fixed(RectF::new(
117 screen_bounds.upper_right()
118 + vec2f(
119 -NOTIFICATION_PADDING - window_size.x(),
120 NOTIFICATION_PADDING,
121 ),
122 window_size,
123 )),
124 titlebar: None,
125 center: false,
126 focus: false,
127 show: true,
128 kind: WindowKind::PopUp,
129 is_movable: false,
130 screen: Some(screen),
131 }
132}