@@ -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.
@@ -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<ui::IconName> {
- 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> {
@@ -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;
@@ -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<D>(deserializer: D) -> Result<Self, D::Error>
+ 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<E>(self, b: bool) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ match b {
+ false => Ok(ChatPanelButton::Never),
+ true => Ok(ChatPanelButton::Always),
+ }
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+ 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<ChatPanelButton>,
+ /// Where to dock the panel.
+ ///
+ /// Default: right
+ pub dock: Option<DockPosition>,
+ /// Default width of the panel in pixels.
+ ///
+ /// Default: 240
+ pub default_width: Option<f32>,
+}
+
#[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<Self::FileContent>,