diff --git a/assets/settings/default.json b/assets/settings/default.json index 5041f79305..9f4f2dc34c 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -481,8 +481,10 @@ "default_width": 240 }, "chat_panel": { - // Whether to show the chat panel button in the status bar. - "button": true, + // When to show the chat panel button in the status bar. + // Can be 'never', 'always', or 'when_in_call', + // or a boolean (interpreted as 'never'/'always'). + "button": "when_in_call", // Where to the chat panel. Can be 'left' or 'right'. "dock": "right", // Default width of the chat panel. diff --git a/crates/collab_ui/src/chat_panel.rs b/crates/collab_ui/src/chat_panel.rs index b330b5b531..75055247cb 100644 --- a/crates/collab_ui/src/chat_panel.rs +++ b/crates/collab_ui/src/chat_panel.rs @@ -1,4 +1,4 @@ -use crate::{collab_panel, ChatPanelSettings}; +use crate::{collab_panel, ChatPanelButton, ChatPanelSettings}; use anyhow::Result; use call::{room, ActiveCall}; use channel::{ChannelChat, ChannelChatEvent, ChannelMessage, ChannelMessageId, ChannelStore}; @@ -1135,7 +1135,14 @@ impl Panel for ChatPanel { } fn icon(&self, cx: &WindowContext) -> Option { - Some(ui::IconName::MessageBubbles).filter(|_| ChatPanelSettings::get_global(cx).button) + match ChatPanelSettings::get_global(cx).button { + ChatPanelButton::Never => None, + ChatPanelButton::Always => Some(ui::IconName::MessageBubbles), + ChatPanelButton::WhenInCall => ActiveCall::global(cx) + .read(cx) + .room() + .map(|_| ui::IconName::MessageBubbles), + } } fn icon_tooltip(&self, _cx: &WindowContext) -> Option<&'static str> { diff --git a/crates/collab_ui/src/collab_ui.rs b/crates/collab_ui/src/collab_ui.rs index 82d10a957e..148e4806cd 100644 --- a/crates/collab_ui/src/collab_ui.rs +++ b/crates/collab_ui/src/collab_ui.rs @@ -14,7 +14,7 @@ use gpui::{ }; use panel_settings::MessageEditorSettings; pub use panel_settings::{ - ChatPanelSettings, CollaborationPanelSettings, NotificationPanelSettings, + ChatPanelButton, ChatPanelSettings, CollaborationPanelSettings, NotificationPanelSettings, }; use release_channel::ReleaseChannel; use settings::Settings; diff --git a/crates/collab_ui/src/panel_settings.rs b/crates/collab_ui/src/panel_settings.rs index f9851d5797..06c43b5611 100644 --- a/crates/collab_ui/src/panel_settings.rs +++ b/crates/collab_ui/src/panel_settings.rs @@ -1,6 +1,6 @@ use gpui::Pixels; use schemars::JsonSchema; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsSources}; use workspace::dock::DockPosition; @@ -11,13 +11,82 @@ pub struct CollaborationPanelSettings { pub default_width: Pixels, } +#[derive(Clone, Copy, Default, Serialize, JsonSchema, Debug)] +#[serde(rename_all = "snake_case")] +pub enum ChatPanelButton { + Never, + Always, + #[default] + WhenInCall, +} + +impl<'de> Deserialize<'de> for ChatPanelButton { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct Visitor; + + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = ChatPanelButton; + + fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + r#"a boolean or one of "never", "always", "when_in_call""# + ) + } + + fn visit_bool(self, b: bool) -> Result + where + E: serde::de::Error, + { + match b { + false => Ok(ChatPanelButton::Never), + true => Ok(ChatPanelButton::Always), + } + } + + fn visit_str(self, s: &str) -> Result + where + E: serde::de::Error, + { + match s { + "never" => Ok(ChatPanelButton::Never), + "always" => Ok(ChatPanelButton::Always), + "when_in_call" => Ok(ChatPanelButton::WhenInCall), + _ => Err(E::unknown_variant(s, &["never", "always", "when_in_call"])), + } + } + } + + deserializer.deserialize_any(Visitor) + } +} + #[derive(Deserialize, Debug)] pub struct ChatPanelSettings { - pub button: bool, + pub button: ChatPanelButton, pub dock: DockPosition, pub default_width: Pixels, } +#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)] +pub struct ChatPanelSettingsContent { + /// When to show the panel button in the status bar. + /// + /// Default: only when in a call + pub button: Option, + /// Where to dock the panel. + /// + /// Default: right + pub dock: Option, + /// Default width of the panel in pixels. + /// + /// Default: 240 + pub default_width: Option, +} + #[derive(Deserialize, Debug)] pub struct NotificationPanelSettings { pub button: bool, @@ -66,7 +135,7 @@ impl Settings for CollaborationPanelSettings { impl Settings for ChatPanelSettings { const KEY: Option<&'static str> = Some("chat_panel"); - type FileContent = PanelSettingsContent; + type FileContent = ChatPanelSettingsContent; fn load( sources: SettingsSources,