diff --git a/Cargo.lock b/Cargo.lock index c40329573deafee2f0ae21f395276b8010f64715..1b7d2038b51b4fc8a966785e856b0904c852abc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -828,6 +828,7 @@ dependencies = [ "media", "postage", "project", + "settings", "util", ] diff --git a/assets/settings/default.json b/assets/settings/default.json index 1ef2ac8a16c9420d5ed019d36a05e1201236849f..6c784a067c143f0f74dfb4fa0d954a19cb87cf12 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -20,6 +20,8 @@ // Whether to pop the completions menu while typing in an editor without // explicitly requesting it. "show_completions_on_input": true, + // Whether the screen sharing icon is showed in the os status bar. + "show_call_status_icon": true, // Whether new projects should start out 'online'. Online projects // appear in the contacts panel under your name, so that your contacts // can see which projects you are working on. Regardless of this diff --git a/crates/call/Cargo.toml b/crates/call/Cargo.toml index 156925fb72e3e12a67f7c4fac935d4fdf7cb916c..54546adb55d5c26e215a610c3d40a65361d3c1ad 100644 --- a/crates/call/Cargo.toml +++ b/crates/call/Cargo.toml @@ -28,6 +28,7 @@ fs = { path = "../fs" } language = { path = "../language" } media = { path = "../media" } project = { path = "../project" } +settings = { path = "../settings" } util = { path = "../util" } anyhow = "1.0.38" diff --git a/crates/call/src/call.rs b/crates/call/src/call.rs index c63b2e0f5bbd67109e25bbd46ea9962570ccf4e5..c34d124162812b709153e769c925432689f7e320 100644 --- a/crates/call/src/call.rs +++ b/crates/call/src/call.rs @@ -1,22 +1,31 @@ +mod indicator; pub mod participant; pub mod room; +use std::sync::Arc; + use anyhow::{anyhow, Result}; use client::{proto, Client, TypedEnvelope, User, UserStore}; use collections::HashSet; +use postage::watch; + use gpui::{ - AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, - Subscription, Task, WeakModelHandle, + actions, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, + Subscription, Task, ViewHandle, WeakModelHandle, }; -pub use participant::ParticipantLocation; -use postage::watch; use project::Project; +use settings::Settings; + +use indicator::SharingStatusIndicator; +pub use participant::ParticipantLocation; pub use room::Room; -use std::sync::Arc; + +actions!(collab, [ToggleScreenSharing]); pub fn init(client: Arc, user_store: ModelHandle, cx: &mut MutableAppContext) { let active_call = cx.add_model(|cx| ActiveCall::new(client, user_store, cx)); cx.set_global(active_call); + cx.add_global_action(toggle_screen_sharing); } #[derive(Clone)] @@ -37,6 +46,7 @@ pub struct ActiveCall { ), client: Arc, user_store: ModelHandle, + sharing_status_indicator: Option<(usize, ViewHandle)>, _subscriptions: Vec, } @@ -61,6 +71,7 @@ impl ActiveCall { ], client, user_store, + sharing_status_indicator: None, } } @@ -279,6 +290,8 @@ impl ActiveCall { this.set_room(None, cx).detach_and_log_err(cx); } + this.set_sharing_status(room.read(cx).is_screen_sharing(), cx); + cx.notify(); }), cx.subscribe(&room, |_, _, event, cx| cx.emit(event.clone())), @@ -303,4 +316,30 @@ impl ActiveCall { pub fn pending_invites(&self) -> &HashSet { &self.pending_invites } + + pub fn set_sharing_status(&mut self, is_screen_sharing: bool, cx: &mut MutableAppContext) { + if is_screen_sharing { + if self.sharing_status_indicator.is_none() + && cx.global::().show_call_status_icon + { + self.sharing_status_indicator = + Some(cx.add_status_bar_item(|_| SharingStatusIndicator)); + } + } else if let Some((window_id, _)) = self.sharing_status_indicator.take() { + cx.remove_status_bar_item(window_id); + } + } +} + +pub fn toggle_screen_sharing(_: &ToggleScreenSharing, cx: &mut MutableAppContext) { + if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() { + let toggle_screen_sharing = room.update(cx, |room, cx| { + if room.is_screen_sharing() { + Task::ready(room.unshare_screen(cx)) + } else { + room.share_screen(cx) + } + }); + toggle_screen_sharing.detach_and_log_err(cx); + } } diff --git a/crates/call/src/indicator.rs b/crates/call/src/indicator.rs new file mode 100644 index 0000000000000000000000000000000000000000..102ea5c551cc465b8e385a6de529fca38335de88 --- /dev/null +++ b/crates/call/src/indicator.rs @@ -0,0 +1,39 @@ +use gpui::{ + color::Color, + elements::{MouseEventHandler, Svg}, + Appearance, Element, ElementBox, Entity, MouseButton, RenderContext, View, +}; + +use crate::ToggleScreenSharing; + +pub struct SharingStatusIndicator; + +impl Entity for SharingStatusIndicator { + type Event = (); +} + +impl View for SharingStatusIndicator { + fn ui_name() -> &'static str { + "SharingStatusIndicator" + } + + fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { + let color = match cx.appearance { + Appearance::Light | Appearance::VibrantLight => Color::black(), + Appearance::Dark | Appearance::VibrantDark => Color::white(), + }; + + MouseEventHandler::::new(0, cx, |_, _| { + Svg::new("icons/disable_screen_sharing_12.svg") + .with_color(color) + .constrained() + .with_width(18.) + .aligned() + .boxed() + }) + .on_click(MouseButton::Left, |_, cx| { + cx.dispatch_action(ToggleScreenSharing); + }) + .boxed() + } +} diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index 3351fb9eb9c14c7f82f0f4d27243776a5b419161..116a331578c54ac8096dd7783774783bac97cd46 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -1,5 +1,5 @@ use crate::{contact_notification::ContactNotification, contacts_popover}; -use call::{ActiveCall, ParticipantLocation}; +use call::{ActiveCall, ParticipantLocation, ToggleScreenSharing}; use client::{proto::PeerId, Authenticate, ContactEventKind, User, UserStore}; use clock::ReplicaId; use contacts_popover::ContactsPopover; @@ -10,21 +10,17 @@ use gpui::{ geometry::{rect::RectF, vector::vec2f, PathBuilder}, json::{self, ToJson}, Border, CursorStyle, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext, - Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, + Subscription, View, ViewContext, ViewHandle, WeakViewHandle, }; use settings::Settings; use std::ops::Range; use theme::Theme; use workspace::{FollowNextCollaborator, JoinProject, ToggleFollow, Workspace}; -actions!( - collab, - [ToggleCollaborationMenu, ToggleScreenSharing, ShareProject] -); +actions!(collab, [ToggleCollaborationMenu, ShareProject]); pub fn init(cx: &mut MutableAppContext) { cx.add_action(CollabTitlebarItem::toggle_contacts_popover); - cx.add_action(CollabTitlebarItem::toggle_screen_sharing); cx.add_action(CollabTitlebarItem::share_project); } @@ -172,19 +168,6 @@ impl CollabTitlebarItem { cx.notify(); } - pub fn toggle_screen_sharing(&mut self, _: &ToggleScreenSharing, cx: &mut ViewContext) { - if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() { - let toggle_screen_sharing = room.update(cx, |room, cx| { - if room.is_screen_sharing() { - Task::ready(room.unshare_screen(cx)) - } else { - room.share_screen(cx) - } - }); - toggle_screen_sharing.detach_and_log_err(cx); - } - } - fn render_toggle_contacts_button( &self, theme: &Theme, diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index a184c9a929eb06464b558a7064eb9198adcb270f..9c4b1f8044f34b1d7be8eb1f9ea170d995c35323 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -35,6 +35,7 @@ pub struct Settings { pub confirm_quit: bool, pub hover_popover_enabled: bool, pub show_completions_on_input: bool, + pub show_call_status_icon: bool, pub vim_mode: bool, pub autosave: Autosave, pub default_dock_anchor: DockAnchor, @@ -287,6 +288,8 @@ pub struct SettingsFileContent { #[serde(default)] pub show_completions_on_input: Option, #[serde(default)] + pub show_call_status_icon: Option, + #[serde(default)] pub vim_mode: Option, #[serde(default)] pub autosave: Option, @@ -346,6 +349,7 @@ impl Settings { cursor_blink: defaults.cursor_blink.unwrap(), hover_popover_enabled: defaults.hover_popover_enabled.unwrap(), show_completions_on_input: defaults.show_completions_on_input.unwrap(), + show_call_status_icon: defaults.show_call_status_icon.unwrap(), vim_mode: defaults.vim_mode.unwrap(), autosave: defaults.autosave.unwrap(), default_dock_anchor: defaults.default_dock_anchor.unwrap(), @@ -540,6 +544,7 @@ impl Settings { cursor_blink: true, hover_popover_enabled: true, show_completions_on_input: true, + show_call_status_icon: true, vim_mode: false, autosave: Autosave::Off, default_dock_anchor: DockAnchor::Bottom, diff --git a/script/start-local-collaboration b/script/start-local-collaboration index 82341bf6db0d15ccb0a1ac84af5841b2279f6716..168ecf7a235bc1de63b04d1464fdea44906c1ec6 100755 --- a/script/start-local-collaboration +++ b/script/start-local-collaboration @@ -31,9 +31,10 @@ scale_factor=1 if [[ $resolution_line =~ Retina ]]; then scale_factor=2; fi width=$(expr ${screen_size[0]} / 2 / $scale_factor) height=${screen_size[1] / $scale_factor} +y=$(expr $height / 2) -position_1=0,0 -position_2=${width},0 +position_1=0,${y} +position_2=${width},${y} # Authenticate using the collab server's admin secret. export ZED_STATELESS=1