Some tweaks for chat panels

Conrad Irwin created

Change summary

crates/collab_ui/src/chat_panel.rs | 189 +++++++++++--------------------
1 file changed, 69 insertions(+), 120 deletions(-)

Detailed changes

crates/collab_ui/src/chat_panel.rs 🔗

@@ -1,4 +1,4 @@
-use crate::{channel_view::ChannelView, is_channels_feature_enabled, ChatPanelSettings};
+use crate::{collab_panel, is_channels_feature_enabled, ChatPanelSettings, CollabPanel};
 use anyhow::Result;
 use call::{room, ActiveCall};
 use channel::{ChannelChat, ChannelChatEvent, ChannelMessageId, ChannelStore};
@@ -7,9 +7,9 @@ use collections::HashMap;
 use db::kvp::KEY_VALUE_STORE;
 use editor::Editor;
 use gpui::{
-    actions, div, list, prelude::*, px, AnyElement, AppContext, AsyncWindowContext, ClickEvent,
-    ElementId, EventEmitter, FocusableView, ListOffset, ListScrollEvent, ListState, Model, Render,
-    Subscription, Task, View, ViewContext, VisualContext, WeakView,
+    actions, div, list, prelude::*, px, Action, AnyElement, AppContext, AsyncWindowContext,
+    ClickEvent, ElementId, EventEmitter, FocusHandle, FocusableView, ListOffset, ListScrollEvent,
+    ListState, Model, Render, Subscription, Task, View, ViewContext, VisualContext, WeakView,
 };
 use language::LanguageRegistry;
 use menu::Confirm;
@@ -21,7 +21,9 @@ use serde::{Deserialize, Serialize};
 use settings::{Settings, SettingsStore};
 use std::sync::Arc;
 use time::{OffsetDateTime, UtcOffset};
-use ui::{prelude::*, Avatar, Button, IconButton, IconName, Label, TabBar, Tooltip};
+use ui::{
+    prelude::*, Avatar, Button, IconButton, IconName, Key, KeyBinding, Label, TabBar, Tooltip,
+};
 use util::{ResultExt, TryFutureExt};
 use workspace::{
     dock::{DockPosition, Panel, PanelEvent},
@@ -55,7 +57,6 @@ pub struct ChatPanel {
     active: bool,
     pending_serialization: Task<Option<()>>,
     subscriptions: Vec<gpui::Subscription>,
-    workspace: WeakView<Workspace>,
     is_scrolled_to_bottom: bool,
     markdown_data: HashMap<ChannelMessageId, RichText>,
 }
@@ -90,8 +91,6 @@ impl ChatPanel {
             )
         });
 
-        let workspace_handle = workspace.weak_handle();
-
         cx.new_view(|cx: &mut ViewContext<Self>| {
             let view = cx.view().downgrade();
             let message_list =
@@ -123,7 +122,6 @@ impl ChatPanel {
                 message_editor: input_editor,
                 local_timezone: cx.local_timezone(),
                 subscriptions: Vec::new(),
-                workspace: workspace_handle,
                 is_scrolled_to_bottom: true,
                 active: false,
                 width: None,
@@ -291,50 +289,6 @@ impl ChatPanel {
         }
     }
 
-    fn render_channel(&self, cx: &mut ViewContext<Self>) -> AnyElement {
-        v_stack()
-            .full()
-            .on_action(cx.listener(Self::send))
-            .child(
-                h_stack().z_index(1).child(
-                    TabBar::new("chat_header")
-                        .child(
-                            h_stack()
-                                .w_full()
-                                .h(rems(ui::Tab::HEIGHT_IN_REMS))
-                                .px_2()
-                                .child(Label::new(
-                                    self.active_chat
-                                        .as_ref()
-                                        .and_then(|c| {
-                                            Some(format!("#{}", c.0.read(cx).channel(cx)?.name))
-                                        })
-                                        .unwrap_or_default(),
-                                )),
-                        )
-                        .end_child(
-                            IconButton::new("notes", IconName::File)
-                                .on_click(cx.listener(Self::open_notes))
-                                .tooltip(|cx| Tooltip::text("Open notes", cx)),
-                        )
-                        .end_child(
-                            IconButton::new("call", IconName::AudioOn)
-                                .on_click(cx.listener(Self::join_call))
-                                .tooltip(|cx| Tooltip::text("Join call", cx)),
-                        ),
-                ),
-            )
-            .child(div().flex_grow().px_2().py_1().map(|this| {
-                if self.active_chat.is_some() {
-                    this.child(list(self.message_list.clone()).full())
-                } else {
-                    this
-                }
-            }))
-            .child(h_stack().p_2().child(self.message_editor.clone()))
-            .into_any()
-    }
-
     fn render_message(&mut self, ix: usize, cx: &mut ViewContext<Self>) -> impl IntoElement {
         let active_chat = &self.active_chat.as_ref().unwrap().0;
         let (message, is_continuation_from_previous, is_continuation_to_next, is_admin) =
@@ -453,44 +407,6 @@ impl ChatPanel {
         rich_text::render_markdown(message.body.clone(), &mentions, language_registry, None)
     }
 
-    fn render_sign_in_prompt(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
-        v_stack()
-            .gap_2()
-            .p_4()
-            .child(
-                Button::new("sign-in", "Sign in")
-                    .style(ButtonStyle::Filled)
-                    .icon_color(Color::Muted)
-                    .icon(IconName::Github)
-                    .icon_position(IconPosition::Start)
-                    .full_width()
-                    .on_click(cx.listener(move |this, _, cx| {
-                        let client = this.client.clone();
-                        cx.spawn(|this, mut cx| async move {
-                            if client
-                                .authenticate_and_connect(true, &cx)
-                                .log_err()
-                                .await
-                                .is_some()
-                            {
-                                this.update(&mut cx, |_, cx| {
-                                    cx.focus_self();
-                                })
-                                .ok();
-                            }
-                        })
-                        .detach();
-                    })),
-            )
-            .child(
-                div().flex().w_full().items_center().child(
-                    Label::new("Sign in to chat.")
-                        .color(Color::Muted)
-                        .size(LabelSize::Small),
-                ),
-            )
-    }
-
     fn send(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
         if let Some((chat, _)) = self.active_chat.as_ref() {
             let message = self
@@ -567,24 +483,6 @@ impl ChatPanel {
             Ok(())
         })
     }
-
-    fn open_notes(&mut self, _: &ClickEvent, cx: &mut ViewContext<Self>) {
-        if let Some((chat, _)) = &self.active_chat {
-            let channel_id = chat.read(cx).channel_id;
-            if let Some(workspace) = self.workspace.upgrade() {
-                ChannelView::open(channel_id, workspace, cx).detach();
-            }
-        }
-    }
-
-    fn join_call(&mut self, _: &ClickEvent, cx: &mut ViewContext<Self>) {
-        if let Some((chat, _)) = &self.active_chat {
-            let channel_id = chat.read(cx).channel_id;
-            ActiveCall::global(cx)
-                .update(cx, |call, cx| call.join_channel(channel_id, cx))
-                .detach_and_log_err(cx);
-        }
-    }
 }
 
 impl EventEmitter<Event> for ChatPanel {}
@@ -592,19 +490,70 @@ impl EventEmitter<Event> for ChatPanel {}
 impl Render for ChatPanel {
     fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
         v_stack()
-            .size_full()
-            .map(|this| match (self.client.user_id(), self.active_chat()) {
-                (Some(_), Some(_)) => this.child(self.render_channel(cx)),
-                (Some(_), None) => this.child(
-                    div().p_4().child(
-                        Label::new("Select a channel to chat in.")
-                            .size(LabelSize::Small)
-                            .color(Color::Muted),
+            .full()
+            .on_action(cx.listener(Self::send))
+            .child(
+                h_stack().z_index(1).child(
+                    TabBar::new("chat_header").child(
+                        h_stack()
+                            .w_full()
+                            .h(rems(ui::Tab::HEIGHT_IN_REMS))
+                            .px_2()
+                            .child(Label::new(
+                                self.active_chat
+                                    .as_ref()
+                                    .and_then(|c| {
+                                        Some(format!("#{}", c.0.read(cx).channel(cx)?.name))
+                                    })
+                                    .unwrap_or("Chat".to_string()),
+                            )),
                     ),
                 ),
-                (None, _) => this.child(self.render_sign_in_prompt(cx)),
-            })
-            .min_w(px(150.))
+            )
+            .child(div().flex_grow().px_2().py_1().map(|this| {
+                if self.active_chat.is_some() {
+                    this.child(list(self.message_list.clone()).full())
+                } else {
+                    this.child(
+                        div()
+                            .p_4()
+                            .child(
+                                Label::new("Select a channel to chat in.")
+                                    .size(LabelSize::Small)
+                                    .color(Color::Muted),
+                            )
+                            .child(
+                                div().pt_1().w_full().items_center().child(
+                                    Button::new("toggle-collab", "Open")
+                                        .full_width()
+                                        .key_binding(KeyBinding::for_action(
+                                            &collab_panel::ToggleFocus,
+                                            cx,
+                                        ))
+                                        .on_click(|_, cx| {
+                                            cx.dispatch_action(
+                                                collab_panel::ToggleFocus.boxed_clone(),
+                                            )
+                                        }),
+                                ),
+                            ),
+                    )
+                }
+            }))
+            .child(h_stack().p_2().map(|el| {
+                if self.active_chat.is_some() {
+                    el.child(self.message_editor.clone())
+                } else {
+                    el.child(
+                        div()
+                            .rounded_md()
+                            .h_7()
+                            .w_full()
+                            .bg(cx.theme().colors().editor_background),
+                    )
+                }
+            }))
+            .into_any()
     }
 }