Move channels panel into collab and rename to collab panel

remove contacts popover and add to collab panel
This commit is contained in:
Mikayla Maki 2023-07-24 14:39:16 -07:00
parent fe5db3035f
commit 7f9df6dd24
No known key found for this signature in database
18 changed files with 95 additions and 292 deletions

28
Cargo.lock generated
View file

@ -1254,31 +1254,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "channels"
version = "0.1.0"
dependencies = [
"anyhow",
"client",
"collections",
"context_menu",
"db",
"editor",
"futures 0.3.28",
"gpui",
"log",
"menu",
"project",
"schemars",
"serde",
"serde_derive",
"serde_json",
"settings",
"theme",
"util",
"workspace",
]
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.26" version = "0.4.26"
@ -1577,6 +1552,7 @@ dependencies = [
"clock", "clock",
"collections", "collections",
"context_menu", "context_menu",
"db",
"editor", "editor",
"feedback", "feedback",
"futures 0.3.28", "futures 0.3.28",
@ -1588,6 +1564,7 @@ dependencies = [
"postage", "postage",
"project", "project",
"recent_projects", "recent_projects",
"schemars",
"serde", "serde",
"serde_derive", "serde_derive",
"settings", "settings",
@ -9882,7 +9859,6 @@ dependencies = [
"backtrace", "backtrace",
"breadcrumbs", "breadcrumbs",
"call", "call",
"channels",
"chrono", "chrono",
"cli", "cli",
"client", "client",

View file

@ -6,7 +6,6 @@ members = [
"crates/auto_update", "crates/auto_update",
"crates/breadcrumbs", "crates/breadcrumbs",
"crates/call", "crates/call",
"crates/channels",
"crates/cli", "crates/cli",
"crates/client", "crates/client",
"crates/clock", "crates/clock",

View file

@ -499,7 +499,8 @@
{ {
"bindings": { "bindings": {
"ctrl-alt-cmd-f": "workspace::FollowNextCollaborator", "ctrl-alt-cmd-f": "workspace::FollowNextCollaborator",
"cmd-shift-c": "collab::ToggleContactsMenu", // TODO: Move this to a dock open action
"cmd-shift-c": "collab_panel::ToggleFocus",
"cmd-alt-i": "zed::DebugElements" "cmd-alt-i": "zed::DebugElements"
} }
}, },

View file

@ -1,38 +0,0 @@
[package]
name = "channels"
version = "0.1.0"
edition = "2021"
publish = false
[lib]
path = "src/channels.rs"
doctest = false
[dependencies]
collections = { path = "../collections" }
context_menu = { path = "../context_menu" }
client = { path = "../client" }
db = { path = "../db" }
editor = { path = "../editor" }
gpui = { path = "../gpui" }
project = { path = "../project" }
theme = { path = "../theme" }
settings = { path = "../settings" }
workspace = { path = "../workspace" }
menu = { path = "../menu" }
util = { path = "../util" }
log.workspace = true
anyhow.workspace = true
schemars.workspace = true
serde_json.workspace = true
serde.workspace = true
serde_derive.workspace = true
futures.workspace = true
[dev-dependencies]
client = { path = "../client", features = ["test-support"] }
editor = { path = "../editor", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] }
workspace = { path = "../workspace", features = ["test-support"] }
serde_json.workspace = true

View file

@ -1,13 +0,0 @@
mod channels_panel;
mod channels_panel_settings;
pub use channels_panel::*;
use gpui::{AppContext};
use std::sync::Arc;
use client::Client;
pub fn init(client: Arc<Client>, cx: &mut AppContext) {
channels_panel::init(cx);
}

View file

@ -23,6 +23,7 @@ test-support = [
[dependencies] [dependencies]
auto_update = { path = "../auto_update" } auto_update = { path = "../auto_update" }
db = { path = "../db" }
call = { path = "../call" } call = { path = "../call" }
client = { path = "../client" } client = { path = "../client" }
clock = { path = "../clock" } clock = { path = "../clock" }
@ -48,6 +49,7 @@ zed-actions = {path = "../zed-actions"}
anyhow.workspace = true anyhow.workspace = true
futures.workspace = true futures.workspace = true
log.workspace = true log.workspace = true
schemars.workspace = true
postage.workspace = true postage.workspace = true
serde.workspace = true serde.workspace = true
serde_derive.workspace = true serde_derive.workspace = true

View file

@ -1,12 +1,11 @@
use crate::{ use crate::{
contact_notification::ContactNotification, contacts_popover, face_pile::FacePile, contact_notification::ContactNotification, face_pile::FacePile,
toggle_deafen, toggle_mute, toggle_screen_sharing, LeaveCall, ToggleDeafen, ToggleMute, toggle_deafen, toggle_mute, toggle_screen_sharing, LeaveCall, ToggleDeafen, ToggleMute,
ToggleScreenSharing, ToggleScreenSharing,
}; };
use call::{ActiveCall, ParticipantLocation, Room}; use call::{ActiveCall, ParticipantLocation, Room};
use client::{proto::PeerId, Client, ContactEventKind, SignIn, SignOut, User, UserStore}; use client::{proto::PeerId, Client, ContactEventKind, SignIn, SignOut, User, UserStore};
use clock::ReplicaId; use clock::ReplicaId;
use contacts_popover::ContactsPopover;
use context_menu::{ContextMenu, ContextMenuItem}; use context_menu::{ContextMenu, ContextMenuItem};
use gpui::{ use gpui::{
actions, actions,
@ -33,7 +32,6 @@ const MAX_BRANCH_NAME_LENGTH: usize = 40;
actions!( actions!(
collab, collab,
[ [
ToggleContactsMenu,
ToggleUserMenu, ToggleUserMenu,
ToggleProjectMenu, ToggleProjectMenu,
SwitchBranch, SwitchBranch,
@ -43,7 +41,6 @@ actions!(
); );
pub fn init(cx: &mut AppContext) { pub fn init(cx: &mut AppContext) {
cx.add_action(CollabTitlebarItem::toggle_contacts_popover);
cx.add_action(CollabTitlebarItem::share_project); cx.add_action(CollabTitlebarItem::share_project);
cx.add_action(CollabTitlebarItem::unshare_project); cx.add_action(CollabTitlebarItem::unshare_project);
cx.add_action(CollabTitlebarItem::toggle_user_menu); cx.add_action(CollabTitlebarItem::toggle_user_menu);
@ -56,7 +53,6 @@ pub struct CollabTitlebarItem {
user_store: ModelHandle<UserStore>, user_store: ModelHandle<UserStore>,
client: Arc<Client>, client: Arc<Client>,
workspace: WeakViewHandle<Workspace>, workspace: WeakViewHandle<Workspace>,
contacts_popover: Option<ViewHandle<ContactsPopover>>,
branch_popover: Option<ViewHandle<BranchList>>, branch_popover: Option<ViewHandle<BranchList>>,
project_popover: Option<ViewHandle<recent_projects::RecentProjects>>, project_popover: Option<ViewHandle<recent_projects::RecentProjects>>,
user_menu: ViewHandle<ContextMenu>, user_menu: ViewHandle<ContextMenu>,
@ -109,7 +105,6 @@ impl View for CollabTitlebarItem {
let status = workspace.read(cx).client().status(); let status = workspace.read(cx).client().status();
let status = &*status.borrow(); let status = &*status.borrow();
if matches!(status, client::Status::Connected { .. }) { if matches!(status, client::Status::Connected { .. }) {
right_container.add_child(self.render_toggle_contacts_button(&theme, cx));
let avatar = user.as_ref().and_then(|user| user.avatar.clone()); let avatar = user.as_ref().and_then(|user| user.avatar.clone());
right_container.add_child(self.render_user_menu_button(&theme, avatar, cx)); right_container.add_child(self.render_user_menu_button(&theme, avatar, cx));
} else { } else {
@ -184,7 +179,6 @@ impl CollabTitlebarItem {
project, project,
user_store, user_store,
client, client,
contacts_popover: None,
user_menu: cx.add_view(|cx| { user_menu: cx.add_view(|cx| {
let view_id = cx.view_id(); let view_id = cx.view_id();
let mut menu = ContextMenu::new(view_id, cx); let mut menu = ContextMenu::new(view_id, cx);
@ -315,9 +309,6 @@ impl CollabTitlebarItem {
} }
fn active_call_changed(&mut self, cx: &mut ViewContext<Self>) { fn active_call_changed(&mut self, cx: &mut ViewContext<Self>) {
if ActiveCall::global(cx).read(cx).room().is_none() {
self.contacts_popover = None;
}
cx.notify(); cx.notify();
} }
@ -337,32 +328,6 @@ impl CollabTitlebarItem {
.log_err(); .log_err();
} }
pub fn toggle_contacts_popover(&mut self, _: &ToggleContactsMenu, cx: &mut ViewContext<Self>) {
if self.contacts_popover.take().is_none() {
let view = cx.add_view(|cx| {
ContactsPopover::new(
self.project.clone(),
self.user_store.clone(),
self.workspace.clone(),
cx,
)
});
cx.subscribe(&view, |this, _, event, cx| {
match event {
contacts_popover::Event::Dismissed => {
this.contacts_popover = None;
}
}
cx.notify();
})
.detach();
self.contacts_popover = Some(view);
}
cx.notify();
}
pub fn toggle_user_menu(&mut self, _: &ToggleUserMenu, cx: &mut ViewContext<Self>) { pub fn toggle_user_menu(&mut self, _: &ToggleUserMenu, cx: &mut ViewContext<Self>) {
self.user_menu.update(cx, |user_menu, cx| { self.user_menu.update(cx, |user_menu, cx| {
let items = if let Some(_) = self.user_store.read(cx).current_user() { let items = if let Some(_) = self.user_store.read(cx).current_user() {
@ -519,79 +484,7 @@ impl CollabTitlebarItem {
} }
cx.notify(); cx.notify();
} }
fn render_toggle_contacts_button(
&self,
theme: &Theme,
cx: &mut ViewContext<Self>,
) -> AnyElement<Self> {
let titlebar = &theme.titlebar;
let badge = if self
.user_store
.read(cx)
.incoming_contact_requests()
.is_empty()
{
None
} else {
Some(
Empty::new()
.collapsed()
.contained()
.with_style(titlebar.toggle_contacts_badge)
.contained()
.with_margin_left(
titlebar
.toggle_contacts_button
.inactive_state()
.default
.icon_width,
)
.with_margin_top(
titlebar
.toggle_contacts_button
.inactive_state()
.default
.icon_width,
)
.aligned(),
)
};
Stack::new()
.with_child(
MouseEventHandler::<ToggleContactsMenu, Self>::new(0, cx, |state, _| {
let style = titlebar
.toggle_contacts_button
.in_state(self.contacts_popover.is_some())
.style_for(state);
Svg::new("icons/radix/person.svg")
.with_color(style.color)
.constrained()
.with_width(style.icon_width)
.aligned()
.constrained()
.with_width(style.button_width)
.with_height(style.button_width)
.contained()
.with_style(style.container)
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, move |_, this, cx| {
this.toggle_contacts_popover(&Default::default(), cx)
})
.with_tooltip::<ToggleContactsMenu>(
0,
"Show contacts menu".into(),
Some(Box::new(ToggleContactsMenu)),
theme.tooltip.clone(),
cx,
),
)
.with_children(badge)
.with_children(self.render_contacts_popover_host(titlebar, cx))
.into_any()
}
fn render_toggle_screen_sharing_button( fn render_toggle_screen_sharing_button(
&self, &self,
theme: &Theme, theme: &Theme,
@ -923,23 +816,6 @@ impl CollabTitlebarItem {
.into_any() .into_any()
} }
fn render_contacts_popover_host<'a>(
&'a self,
_theme: &'a theme::Titlebar,
cx: &'a ViewContext<Self>,
) -> Option<AnyElement<Self>> {
self.contacts_popover.as_ref().map(|popover| {
Overlay::new(ChildView::new(popover, cx))
.with_fit_mode(OverlayFitMode::SwitchAnchor)
.with_anchor_corner(AnchorCorner::TopLeft)
.with_z_index(999)
.aligned()
.bottom()
.right()
.into_any()
})
}
fn render_collaborators( fn render_collaborators(
&self, &self,
workspace: &ViewHandle<Workspace>, workspace: &ViewHandle<Workspace>,

View file

@ -1,16 +1,14 @@
mod collab_titlebar_item; mod collab_titlebar_item;
mod contact_finder;
mod contact_list;
mod contact_notification; mod contact_notification;
mod contacts_popover;
mod face_pile; mod face_pile;
mod incoming_call_notification; mod incoming_call_notification;
mod notifications; mod notifications;
mod project_shared_notification; mod project_shared_notification;
mod sharing_status_indicator; mod sharing_status_indicator;
pub mod panel;
use call::{ActiveCall, Room}; use call::{ActiveCall, Room};
pub use collab_titlebar_item::{CollabTitlebarItem, ToggleContactsMenu}; pub use collab_titlebar_item::CollabTitlebarItem;
use gpui::{actions, AppContext, Task}; use gpui::{actions, AppContext, Task};
use std::sync::Arc; use std::sync::Arc;
use util::ResultExt; use util::ResultExt;
@ -24,9 +22,7 @@ actions!(
pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) { pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
vcs_menu::init(cx); vcs_menu::init(cx);
collab_titlebar_item::init(cx); collab_titlebar_item::init(cx);
contact_list::init(cx); panel::init(app_state.client.clone(), cx);
contact_finder::init(cx);
contacts_popover::init(cx);
incoming_call_notification::init(&app_state, cx); incoming_call_notification::init(&app_state, cx);
project_shared_notification::init(&app_state, cx); project_shared_notification::init(&app_state, cx);
sharing_status_indicator::init(cx); sharing_status_indicator::init(cx);

View file

@ -1,15 +1,17 @@
mod contacts;
mod panel_settings;
use std::sync::Arc; use std::sync::Arc;
use crate::channels_panel_settings::{ChannelsPanelDockPosition, ChannelsPanelSettings};
use anyhow::Result; use anyhow::Result;
use collections::HashMap; use client::Client;
use context_menu::ContextMenu; use context_menu::ContextMenu;
use db::kvp::KEY_VALUE_STORE; use db::kvp::KEY_VALUE_STORE;
use gpui::{ use gpui::{
actions, actions,
elements::{ChildView, Flex, Label, ParentElement, Stack}, elements::{ChildView, Flex, Label, ParentElement, Stack},
serde_json, AppContext, AsyncAppContext, Element, Entity, Task, View, ViewContext, serde_json, AppContext, AsyncAppContext, Element, Entity, Task, View, ViewContext, ViewHandle,
ViewHandle, WeakViewHandle, WeakViewHandle,
}; };
use project::Fs; use project::Fs;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
@ -20,27 +22,32 @@ use workspace::{
Workspace, Workspace,
}; };
actions!(channels, [ToggleFocus]); use self::{
contacts::Contacts,
panel_settings::{ChannelsPanelDockPosition, ChannelsPanelSettings},
};
actions!(collab_panel, [ToggleFocus]);
const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel"; const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel";
pub fn init(cx: &mut AppContext) { pub fn init(_client: Arc<Client>, cx: &mut AppContext) {
settings::register::<ChannelsPanelSettings>(cx); settings::register::<panel_settings::ChannelsPanelSettings>(cx);
contacts::init(cx);
} }
pub struct ChannelsPanel { pub struct CollabPanel {
width: Option<f32>, width: Option<f32>,
fs: Arc<dyn Fs>, fs: Arc<dyn Fs>,
has_focus: bool, has_focus: bool,
pending_serialization: Task<Option<()>>, pending_serialization: Task<Option<()>>,
context_menu: ViewHandle<ContextMenu>, context_menu: ViewHandle<ContextMenu>,
collapsed_channels: HashMap<u64, bool>, contacts: ViewHandle<contacts::Contacts>,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct SerializedChannelsPanel { struct SerializedChannelsPanel {
width: Option<f32>, width: Option<f32>,
collapsed_channels: Option<HashMap<u64, bool>>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -49,26 +56,34 @@ pub enum Event {
Focus, Focus,
} }
impl Entity for ChannelsPanel { impl Entity for CollabPanel {
type Event = Event; type Event = Event;
} }
impl ChannelsPanel { impl CollabPanel {
pub fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> ViewHandle<Self> { pub fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> ViewHandle<Self> {
cx.add_view(|cx| { cx.add_view(|cx| {
let view_id = cx.view_id(); let view_id = cx.view_id();
let this = Self { let this = Self {
width: None, width: None,
has_focus: false, has_focus: false,
fs: workspace.app_state().fs.clone(), fs: workspace.app_state().fs.clone(),
pending_serialization: Task::ready(None), pending_serialization: Task::ready(None),
context_menu: cx.add_view(|cx| ContextMenu::new(view_id, cx)), context_menu: cx.add_view(|cx| ContextMenu::new(view_id, cx)),
collapsed_channels: HashMap::default(), contacts: cx.add_view(|cx| {
Contacts::new(
workspace.project().clone(),
workspace.user_store().clone(),
workspace.weak_handle(),
cx,
)
}),
}; };
// Update the dock position when the setting changes. // Update the dock position when the setting changes.
let mut old_dock_position = this.position(cx); let mut old_dock_position = this.position(cx);
cx.observe_global::<SettingsStore, _>(move |this: &mut ChannelsPanel, cx| { cx.observe_global::<SettingsStore, _>(move |this: &mut CollabPanel, cx| {
let new_dock_position = this.position(cx); let new_dock_position = this.position(cx);
if new_dock_position != old_dock_position { if new_dock_position != old_dock_position {
old_dock_position = new_dock_position; old_dock_position = new_dock_position;
@ -99,12 +114,10 @@ impl ChannelsPanel {
}; };
workspace.update(&mut cx, |workspace, cx| { workspace.update(&mut cx, |workspace, cx| {
let panel = ChannelsPanel::new(workspace, cx); let panel = CollabPanel::new(workspace, cx);
if let Some(serialized_panel) = serialized_panel { if let Some(serialized_panel) = serialized_panel {
panel.update(cx, |panel, cx| { panel.update(cx, |panel, cx| {
panel.width = serialized_panel.width; panel.width = serialized_panel.width;
panel.collapsed_channels =
serialized_panel.collapsed_channels.unwrap_or_default();
cx.notify(); cx.notify();
}); });
} }
@ -115,16 +128,12 @@ impl ChannelsPanel {
fn serialize(&mut self, cx: &mut ViewContext<Self>) { fn serialize(&mut self, cx: &mut ViewContext<Self>) {
let width = self.width; let width = self.width;
let collapsed_channels = self.collapsed_channels.clone();
self.pending_serialization = cx.background().spawn( self.pending_serialization = cx.background().spawn(
async move { async move {
KEY_VALUE_STORE KEY_VALUE_STORE
.write_kvp( .write_kvp(
CHANNELS_PANEL_KEY.into(), CHANNELS_PANEL_KEY.into(),
serde_json::to_string(&SerializedChannelsPanel { serde_json::to_string(&SerializedChannelsPanel { width })?,
width,
collapsed_channels: Some(collapsed_channels),
})?,
) )
.await?; .await?;
anyhow::Ok(()) anyhow::Ok(())
@ -134,7 +143,7 @@ impl ChannelsPanel {
} }
} }
impl View for ChannelsPanel { impl View for CollabPanel {
fn ui_name() -> &'static str { fn ui_name() -> &'static str {
"ChannelsPanel" "ChannelsPanel"
} }
@ -159,18 +168,19 @@ impl View for ChannelsPanel {
// Full panel column // Full panel column
Flex::column() Flex::column()
.with_child( .with_child(
Flex::column().with_child( Flex::column()
Flex::row().with_child( .with_child(
Label::new( Flex::row().with_child(
"Contacts", Label::new(
theme.editor.invalid_information_diagnostic.message.clone(), "Contacts",
) theme.editor.invalid_information_diagnostic.message.clone(),
.into_any(), )
), .into_any(),
), ),
)
.with_child(ChildView::new(&self.contacts, cx)),
) )
.scrollable::<ChannelsPanelScrollTag>(0, None, cx) .scrollable::<ChannelsPanelScrollTag>(0, None, cx),
.expanded(),
) )
.with_child(ChildView::new(&self.context_menu, cx)) .with_child(ChildView::new(&self.context_menu, cx))
.into_any_named("channels panel") .into_any_named("channels panel")
@ -178,7 +188,7 @@ impl View for ChannelsPanel {
} }
} }
impl Panel for ChannelsPanel { impl Panel for CollabPanel {
fn position(&self, cx: &gpui::WindowContext) -> DockPosition { fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
match settings::get::<ChannelsPanelSettings>(cx).dock { match settings::get::<ChannelsPanelSettings>(cx).dock {
ChannelsPanelDockPosition::Left => DockPosition::Left, ChannelsPanelDockPosition::Left => DockPosition::Left,
@ -216,7 +226,7 @@ impl Panel for ChannelsPanel {
} }
fn icon_path(&self) -> &'static str { fn icon_path(&self) -> &'static str {
"icons/bolt_16.svg" "icons/radix/person.svg"
} }
fn icon_tooltip(&self) -> (String, Option<Box<dyn gpui::Action>>) { fn icon_tooltip(&self) -> (String, Option<Box<dyn gpui::Action>>) {

View file

@ -1,7 +1,6 @@
use crate::{ mod contact_finder;
contact_finder::{build_contact_finder, ContactFinder}, mod contacts_list;
contact_list::ContactList,
};
use client::UserStore; use client::UserStore;
use gpui::{ use gpui::{
actions, elements::*, platform::MouseButton, AppContext, Entity, ModelHandle, View, actions, elements::*, platform::MouseButton, AppContext, Entity, ModelHandle, View,
@ -11,10 +10,14 @@ use picker::PickerEvent;
use project::Project; use project::Project;
use workspace::Workspace; use workspace::Workspace;
use self::{contacts_list::ContactList, contact_finder::{ContactFinder, build_contact_finder}};
actions!(contacts_popover, [ToggleContactFinder]); actions!(contacts_popover, [ToggleContactFinder]);
pub fn init(cx: &mut AppContext) { pub fn init(cx: &mut AppContext) {
cx.add_action(ContactsPopover::toggle_contact_finder); cx.add_action(Contacts::toggle_contact_finder);
contact_finder::init(cx);
contacts_list::init(cx);
} }
pub enum Event { pub enum Event {
@ -26,7 +29,7 @@ enum Child {
ContactFinder(ViewHandle<ContactFinder>), ContactFinder(ViewHandle<ContactFinder>),
} }
pub struct ContactsPopover { pub struct Contacts {
child: Child, child: Child,
project: ModelHandle<Project>, project: ModelHandle<Project>,
user_store: ModelHandle<UserStore>, user_store: ModelHandle<UserStore>,
@ -34,7 +37,7 @@ pub struct ContactsPopover {
_subscription: Option<gpui::Subscription>, _subscription: Option<gpui::Subscription>,
} }
impl ContactsPopover { impl Contacts {
pub fn new( pub fn new(
project: ModelHandle<Project>, project: ModelHandle<Project>,
user_store: ModelHandle<UserStore>, user_store: ModelHandle<UserStore>,
@ -61,7 +64,7 @@ impl ContactsPopover {
} }
} }
fn show_contact_finder(&mut self, editor_text: String, cx: &mut ViewContext<ContactsPopover>) { fn show_contact_finder(&mut self, editor_text: String, cx: &mut ViewContext<Contacts>) {
let child = cx.add_view(|cx| { let child = cx.add_view(|cx| {
let finder = build_contact_finder(self.user_store.clone(), cx); let finder = build_contact_finder(self.user_store.clone(), cx);
finder.set_query(editor_text, cx); finder.set_query(editor_text, cx);
@ -75,7 +78,7 @@ impl ContactsPopover {
cx.notify(); cx.notify();
} }
fn show_contact_list(&mut self, editor_text: String, cx: &mut ViewContext<ContactsPopover>) { fn show_contact_list(&mut self, editor_text: String, cx: &mut ViewContext<Contacts>) {
let child = cx.add_view(|cx| { let child = cx.add_view(|cx| {
ContactList::new( ContactList::new(
self.project.clone(), self.project.clone(),
@ -87,8 +90,8 @@ impl ContactsPopover {
}); });
cx.focus(&child); cx.focus(&child);
self._subscription = Some(cx.subscribe(&child, |this, _, event, cx| match event { self._subscription = Some(cx.subscribe(&child, |this, _, event, cx| match event {
crate::contact_list::Event::Dismissed => cx.emit(Event::Dismissed), contacts_list::Event::Dismissed => cx.emit(Event::Dismissed),
crate::contact_list::Event::ToggleContactFinder => { contacts_list::Event::ToggleContactFinder => {
this.toggle_contact_finder(&Default::default(), cx) this.toggle_contact_finder(&Default::default(), cx)
} }
})); }));
@ -97,11 +100,11 @@ impl ContactsPopover {
} }
} }
impl Entity for ContactsPopover { impl Entity for Contacts {
type Event = Event; type Event = Event;
} }
impl View for ContactsPopover { impl View for Contacts {
fn ui_name() -> &'static str { fn ui_name() -> &'static str {
"ContactsPopover" "ContactsPopover"
} }
@ -113,9 +116,9 @@ impl View for ContactsPopover {
Child::ContactFinder(child) => ChildView::new(child, cx), Child::ContactFinder(child) => ChildView::new(child, cx),
}; };
MouseEventHandler::<ContactsPopover, Self>::new(0, cx, |_, _| { MouseEventHandler::<Contacts, Self>::new(0, cx, |_, _| {
Flex::column() Flex::column()
.with_child(child.flex(1., true)) .with_child(child)
.contained() .contained()
.with_style(theme.contacts_popover.container) .with_style(theme.contacts_popover.container)
.constrained() .constrained()

View file

@ -1326,12 +1326,11 @@ impl View for ContactList {
Flex::column() Flex::column()
.with_child( .with_child(
Flex::row() Flex::row()
.with_child( // .with_child(
ChildView::new(&self.filter_editor, cx) // ChildView::new(&self.filter_editor, cx)
.contained() // .contained()
.with_style(theme.contact_list.user_query_editor.container) // .with_style(theme.contact_list.user_query_editor.container)
.flex(1., true), // )
)
.with_child( .with_child(
MouseEventHandler::<AddContact, Self>::new(0, cx, |_, _| { MouseEventHandler::<AddContact, Self>::new(0, cx, |_, _| {
render_icon_button( render_icon_button(
@ -1354,7 +1353,7 @@ impl View for ContactList {
.constrained() .constrained()
.with_height(theme.contact_list.user_query_editor_height), .with_height(theme.contact_list.user_query_editor_height),
) )
.with_child(List::new(self.list_state.clone()).flex(1., false)) // .with_child(List::new(self.list_state.clone()))
.into_any() .into_any()
} }

View file

@ -47,6 +47,10 @@ pub trait Element<V: View>: 'static {
type LayoutState; type LayoutState;
type PaintState; type PaintState;
fn view_name(&self) -> &'static str {
V::ui_name()
}
fn layout( fn layout(
&mut self, &mut self,
constraint: SizeConstraint, constraint: SizeConstraint,
@ -267,8 +271,8 @@ impl<V: View, E: Element<V>> AnyElementState<V> for ElementState<V, E> {
| ElementState::PostLayout { mut element, .. } | ElementState::PostLayout { mut element, .. }
| ElementState::PostPaint { mut element, .. } => { | ElementState::PostPaint { mut element, .. } => {
let (size, layout) = element.layout(constraint, view, cx); let (size, layout) = element.layout(constraint, view, cx);
debug_assert!(size.x().is_finite()); debug_assert!(size.x().is_finite(), "Element for {:?} had infinite x size after layout", element.view_name());
debug_assert!(size.y().is_finite()); debug_assert!(size.y().is_finite(), "Element for {:?} had infinite x size after layout", element.view_name());
result = size; result = size;
ElementState::PostLayout { ElementState::PostLayout {

View file

@ -1,3 +1,5 @@
#![allow(non_snake_case)]
use super::{entity_messages, messages, request_messages, ConnectionId, TypedEnvelope}; use super::{entity_messages, messages, request_messages, ConnectionId, TypedEnvelope};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use async_tungstenite::tungstenite::Message as WebSocketMessage; use async_tungstenite::tungstenite::Message as WebSocketMessage;

View file

@ -21,7 +21,6 @@ activity_indicator = { path = "../activity_indicator" }
auto_update = { path = "../auto_update" } auto_update = { path = "../auto_update" }
breadcrumbs = { path = "../breadcrumbs" } breadcrumbs = { path = "../breadcrumbs" }
call = { path = "../call" } call = { path = "../call" }
channels = { path = "../channels" }
cli = { path = "../cli" } cli = { path = "../cli" }
collab_ui = { path = "../collab_ui" } collab_ui = { path = "../collab_ui" }
collections = { path = "../collections" } collections = { path = "../collections" }

View file

@ -155,7 +155,6 @@ fn main() {
outline::init(cx); outline::init(cx);
project_symbols::init(cx); project_symbols::init(cx);
project_panel::init(Assets, cx); project_panel::init(Assets, cx);
channels::init(client.clone(), cx);
diagnostics::init(cx); diagnostics::init(cx);
search::init(cx); search::init(cx);
semantic_index::init(fs.clone(), http.clone(), languages.clone(), cx); semantic_index::init(fs.clone(), http.clone(), languages.clone(), cx);

View file

@ -9,9 +9,8 @@ use ai::AssistantPanel;
use anyhow::Context; use anyhow::Context;
use assets::Assets; use assets::Assets;
use breadcrumbs::Breadcrumbs; use breadcrumbs::Breadcrumbs;
use channels::ChannelsPanel;
pub use client; pub use client;
use collab_ui::{CollabTitlebarItem, ToggleContactsMenu}; use collab_ui::CollabTitlebarItem; // TODO: Add back toggle collab ui shortcut
use collections::VecDeque; use collections::VecDeque;
pub use editor; pub use editor;
use editor::{Editor, MultiBuffer}; use editor::{Editor, MultiBuffer};
@ -86,20 +85,6 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
cx.toggle_full_screen(); cx.toggle_full_screen();
}, },
); );
cx.add_action(
|workspace: &mut Workspace, _: &ToggleContactsMenu, cx: &mut ViewContext<Workspace>| {
if let Some(item) = workspace
.titlebar_item()
.and_then(|item| item.downcast::<CollabTitlebarItem>())
{
cx.defer(move |_, cx| {
item.update(cx, |item, cx| {
item.toggle_contacts_popover(&Default::default(), cx);
});
});
}
},
);
cx.add_global_action(quit); cx.add_global_action(quit);
cx.add_global_action(move |action: &OpenBrowser, cx| cx.platform().open_url(&action.url)); cx.add_global_action(move |action: &OpenBrowser, cx| cx.platform().open_url(&action.url));
cx.add_global_action(move |_: &IncreaseBufferFontSize, cx| { cx.add_global_action(move |_: &IncreaseBufferFontSize, cx| {
@ -223,8 +208,10 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
}, },
); );
cx.add_action( cx.add_action(
|workspace: &mut Workspace, _: &channels::ToggleFocus, cx: &mut ViewContext<Workspace>| { |workspace: &mut Workspace,
workspace.toggle_panel_focus::<channels::ChannelsPanel>(cx); _: &collab_ui::panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<collab_ui::panel::CollabPanel>(cx);
}, },
); );
cx.add_action( cx.add_action(
@ -345,7 +332,8 @@ pub fn initialize_workspace(
let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone()); let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone()); let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone()); let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
let channels_panel = ChannelsPanel::load(workspace_handle.clone(), cx.clone()); let channels_panel =
collab_ui::panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
let (project_panel, terminal_panel, assistant_panel, channels_panel) = futures::try_join!( let (project_panel, terminal_panel, assistant_panel, channels_panel) = futures::try_join!(
project_panel, project_panel,
terminal_panel, terminal_panel,