Move channels panel into collab and rename to collab panel
remove contacts popover and add to collab panel
This commit is contained in:
parent
fe5db3035f
commit
7f9df6dd24
18 changed files with 95 additions and 292 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>>) {
|
|
@ -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()
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue