Cargo.lock 🔗
@@ -7154,6 +7154,7 @@ dependencies = [
"auto_update",
"backtrace",
"breadcrumbs",
+ "call",
"chat_panel",
"chrono",
"cli",
Antonio Scandurra and Nathan Sobo created
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
Cargo.lock | 1
crates/call/src/call.rs | 77 +++++++--------
crates/collab_ui/src/collab_titlebar_item.rs | 3
crates/collab_ui/src/collab_ui.rs | 7
crates/collab_ui/src/contacts_popover.rs | 26 +---
crates/collab_ui/src/incoming_call_notification.rs | 31 +-----
crates/zed/Cargo.toml | 7 +
crates/zed/src/main.rs | 2
crates/zed/src/zed.rs | 1
9 files changed, 63 insertions(+), 92 deletions(-)
@@ -7154,6 +7154,7 @@ dependencies = [
"auto_update",
"backtrace",
"breadcrumbs",
+ "call",
"chat_panel",
"chrono",
"cli",
@@ -6,11 +6,16 @@ use client::{incoming_call::IncomingCall, Client, UserStore};
use gpui::{Entity, ModelContext, ModelHandle, MutableAppContext, Task};
pub use room::Room;
use std::sync::Arc;
-use util::ResultExt;
-#[derive(Default)]
+pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
+ let active_call = cx.add_model(|_| ActiveCall::new(client, user_store));
+ cx.set_global(active_call);
+}
+
pub struct ActiveCall {
room: Option<ModelHandle<Room>>,
+ client: Arc<Client>,
+ user_store: ModelHandle<UserStore>,
}
impl Entity for ActiveCall {
@@ -18,68 +23,62 @@ impl Entity for ActiveCall {
}
impl ActiveCall {
- pub fn global(cx: &mut MutableAppContext) -> ModelHandle<Self> {
- if cx.has_global::<ModelHandle<Self>>() {
- cx.global::<ModelHandle<Self>>().clone()
- } else {
- let active_call = cx.add_model(|_| ActiveCall::default());
- cx.set_global(active_call.clone());
- active_call
+ fn new(client: Arc<Client>, user_store: ModelHandle<UserStore>) -> Self {
+ Self {
+ room: None,
+ client,
+ user_store,
}
}
- pub fn get_or_create(
+ pub fn global(cx: &mut MutableAppContext) -> ModelHandle<Self> {
+ cx.global::<ModelHandle<Self>>().clone()
+ }
+
+ pub fn invite(
&mut self,
- client: &Arc<Client>,
- user_store: &ModelHandle<UserStore>,
+ recipient_user_id: u64,
cx: &mut ModelContext<Self>,
- ) -> Task<Result<ModelHandle<Room>>> {
- if let Some(room) = self.room.clone() {
- Task::ready(Ok(room))
- } else {
- let client = client.clone();
- let user_store = user_store.clone();
- cx.spawn(|this, mut cx| async move {
+ ) -> Task<Result<()>> {
+ let room = self.room.clone();
+
+ let client = self.client.clone();
+ let user_store = self.user_store.clone();
+ cx.spawn(|this, mut cx| async move {
+ let room = if let Some(room) = room {
+ room
+ } else {
let room = cx.update(|cx| Room::create(client, user_store, cx)).await?;
this.update(&mut cx, |this, cx| {
this.room = Some(room.clone());
cx.notify();
});
- Ok(room)
- })
- }
+ room
+ };
+ room.update(&mut cx, |room, cx| room.call(recipient_user_id, cx))
+ .await?;
+
+ Ok(())
+ })
}
- pub fn join(
- &mut self,
- call: &IncomingCall,
- client: &Arc<Client>,
- user_store: &ModelHandle<UserStore>,
- cx: &mut ModelContext<Self>,
- ) -> Task<Result<ModelHandle<Room>>> {
+ pub fn join(&mut self, call: &IncomingCall, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
if self.room.is_some() {
return Task::ready(Err(anyhow!("cannot join while on another call")));
}
- let join = Room::join(call, client.clone(), user_store.clone(), cx);
+ let join = Room::join(call, self.client.clone(), self.user_store.clone(), cx);
cx.spawn(|this, mut cx| async move {
let room = join.await?;
this.update(&mut cx, |this, cx| {
- this.room = Some(room.clone());
+ this.room = Some(room);
cx.notify();
});
- Ok(room)
+ Ok(())
})
}
pub fn room(&self) -> Option<&ModelHandle<Room>> {
self.room.as_ref()
}
-
- pub fn clear(&mut self, cx: &mut ModelContext<Self>) {
- if let Some(room) = self.room.take() {
- room.update(cx, |room, cx| room.leave(cx)).log_err();
- cx.notify();
- }
- }
}
@@ -69,9 +69,8 @@ impl CollabTitlebarItem {
Some(_) => {}
None => {
if let Some(workspace) = self.workspace.upgrade(cx) {
- let client = workspace.read(cx).client().clone();
let user_store = workspace.read(cx).user_store().clone();
- let view = cx.add_view(|cx| ContactsPopover::new(client, user_store, cx));
+ let view = cx.add_view(|cx| ContactsPopover::new(user_store, cx));
cx.focus(&view);
cx.subscribe(&view, |this, _, event, cx| {
match event {
@@ -2,13 +2,12 @@ mod collab_titlebar_item;
mod contacts_popover;
mod incoming_call_notification;
-use client::{Client, UserStore};
+use client::UserStore;
pub use collab_titlebar_item::CollabTitlebarItem;
use gpui::{ModelHandle, MutableAppContext};
-use std::sync::Arc;
-pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
+pub fn init(user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
contacts_popover::init(cx);
collab_titlebar_item::init(cx);
- incoming_call_notification::init(client, user_store, cx);
+ incoming_call_notification::init(user_store, cx);
}
@@ -1,7 +1,7 @@
use std::sync::Arc;
use call::ActiveCall;
-use client::{Client, Contact, User, UserStore};
+use client::{Contact, User, UserStore};
use editor::{Cancel, Editor};
use fuzzy::{match_strings, StringMatchCandidate};
use gpui::{
@@ -84,7 +84,6 @@ pub struct ContactsPopover {
entries: Vec<ContactEntry>,
match_candidates: Vec<StringMatchCandidate>,
list_state: ListState,
- client: Arc<Client>,
user_store: ModelHandle<UserStore>,
filter_editor: ViewHandle<Editor>,
collapsed_sections: Vec<Section>,
@@ -93,11 +92,7 @@ pub struct ContactsPopover {
}
impl ContactsPopover {
- pub fn new(
- client: Arc<Client>,
- user_store: ModelHandle<UserStore>,
- cx: &mut ViewContext<Self>,
- ) -> Self {
+ pub fn new(user_store: ModelHandle<UserStore>, cx: &mut ViewContext<Self>) -> Self {
let filter_editor = cx.add_view(|cx| {
let mut editor = Editor::single_line(
Some(|theme| theme.contacts_panel.user_query_editor.clone()),
@@ -182,7 +177,6 @@ impl ContactsPopover {
match_candidates: Default::default(),
filter_editor,
_subscriptions: subscriptions,
- client,
user_store,
};
this.update_entries(cx);
@@ -633,17 +627,11 @@ impl ContactsPopover {
}
fn call(&mut self, action: &Call, cx: &mut ViewContext<Self>) {
- let recipient_user_id = action.recipient_user_id;
- let room = ActiveCall::global(cx).update(cx, |active_call, cx| {
- active_call.get_or_create(&self.client, &self.user_store, cx)
- });
- cx.spawn_weak(|_, mut cx| async move {
- let room = room.await?;
- room.update(&mut cx, |room, cx| room.call(recipient_user_id, cx))
- .await?;
- anyhow::Ok(())
- })
- .detach();
+ ActiveCall::global(cx)
+ .update(cx, |active_call, cx| {
+ active_call.invite(action.recipient_user_id, cx)
+ })
+ .detach_and_log_err(cx);
}
}
@@ -1,7 +1,5 @@
-use std::sync::Arc;
-
use call::ActiveCall;
-use client::{incoming_call::IncomingCall, Client, UserStore};
+use client::{incoming_call::IncomingCall, UserStore};
use futures::StreamExt;
use gpui::{
elements::*,
@@ -14,7 +12,7 @@ use util::ResultExt;
impl_internal_actions!(incoming_call_notification, [RespondToCall]);
-pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
+pub fn init(user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
cx.add_action(IncomingCallNotification::respond_to_call);
let mut incoming_call = user_store.read(cx).incoming_call();
@@ -34,13 +32,7 @@ pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut Mu
kind: WindowKind::PopUp,
is_movable: false,
},
- |_| {
- IncomingCallNotification::new(
- incoming_call,
- client.clone(),
- user_store.clone(),
- )
- },
+ |_| IncomingCallNotification::new(incoming_call, user_store.clone()),
);
notification_window = Some(window_id);
}
@@ -56,29 +48,18 @@ struct RespondToCall {
pub struct IncomingCallNotification {
call: IncomingCall,
- client: Arc<Client>,
user_store: ModelHandle<UserStore>,
}
impl IncomingCallNotification {
- pub fn new(
- call: IncomingCall,
- client: Arc<Client>,
- user_store: ModelHandle<UserStore>,
- ) -> Self {
- Self {
- call,
- client,
- user_store,
- }
+ pub fn new(call: IncomingCall, user_store: ModelHandle<UserStore>) -> Self {
+ Self { call, user_store }
}
fn respond_to_call(&mut self, action: &RespondToCall, cx: &mut ViewContext<Self>) {
if action.accept {
ActiveCall::global(cx)
- .update(cx, |active_call, cx| {
- active_call.join(&self.call, &self.client, &self.user_store, cx)
- })
+ .update(cx, |active_call, cx| active_call.join(&self.call, cx))
.detach_and_log_err(cx);
} else {
self.user_store
@@ -19,6 +19,7 @@ activity_indicator = { path = "../activity_indicator" }
assets = { path = "../assets" }
auto_update = { path = "../auto_update" }
breadcrumbs = { path = "../breadcrumbs" }
+call = { path = "../call" }
chat_panel = { path = "../chat_panel" }
cli = { path = "../cli" }
collab_ui = { path = "../collab_ui" }
@@ -103,17 +104,19 @@ tree-sitter-typescript = "0.20.1"
url = "2.2"
[dev-dependencies]
-text = { path = "../text", features = ["test-support"] }
+call = { path = "../call", features = ["test-support"] }
+client = { path = "../client", features = ["test-support"] }
editor = { path = "../editor", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] }
language = { path = "../language", features = ["test-support"] }
lsp = { path = "../lsp", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] }
rpc = { path = "../rpc", features = ["test-support"] }
-client = { path = "../client", features = ["test-support"] }
settings = { path = "../settings", features = ["test-support"] }
+text = { path = "../text", features = ["test-support"] }
util = { path = "../util", features = ["test-support"] }
workspace = { path = "../workspace", features = ["test-support"] }
+
env_logger = "0.9"
serde_json = { version = "1.0", features = ["preserve_order"] }
unindent = "0.1.7"
@@ -107,7 +107,7 @@ fn main() {
project::Project::init(&client);
client::Channel::init(&client);
client::init(client.clone(), cx);
- collab_ui::init(client.clone(), user_store.clone(), cx);
+ collab_ui::init(user_store.clone(), cx);
command_palette::init(cx);
editor::init(cx);
go_to_line::init(cx);
@@ -217,6 +217,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
);
activity_indicator::init(cx);
+ call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
settings::KeymapFileContent::load_defaults(cx);
}