Cargo.lock 🔗
@@ -693,6 +693,7 @@ dependencies = [
"collections",
"futures",
"gpui",
+ "postage",
"project",
"util",
]
Antonio Scandurra created
Cargo.lock | 1
crates/call/Cargo.toml | 1
crates/call/src/call.rs | 93 +++
crates/call/src/room.rs | 8
crates/client/src/user.rs | 58 --
crates/collab/src/integration_tests.rs | 463 +++++++--------
crates/collab_ui/src/collab_ui.rs | 2
crates/collab_ui/src/incoming_call_notification.rs | 29
crates/gpui/src/app.rs | 4
crates/gpui/src/test.rs | 2
crates/gpui_macros/src/gpui_macros.rs | 2
11 files changed, 334 insertions(+), 329 deletions(-)
@@ -693,6 +693,7 @@ dependencies = [
"collections",
"futures",
"gpui",
+ "postage",
"project",
"util",
]
@@ -25,6 +25,7 @@ util = { path = "../util" }
anyhow = "1.0.38"
futures = "0.3"
+postage = { version = "0.4.1", features = ["futures-traits"] }
[dev-dependencies]
client = { path = "../client", features = ["test-support"] }
@@ -2,22 +2,31 @@ mod participant;
pub mod room;
use anyhow::{anyhow, Result};
-use client::{incoming_call::IncomingCall, Client, UserStore};
-use gpui::{AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Subscription, Task};
+use client::{incoming_call::IncomingCall, proto, Client, TypedEnvelope, UserStore};
+use gpui::{
+ AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext,
+ Subscription, Task,
+};
pub use participant::ParticipantLocation;
+use postage::watch;
use project::Project;
pub use room::Room;
use std::sync::Arc;
pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
- let active_call = cx.add_model(|_| ActiveCall::new(client, user_store));
+ let active_call = cx.add_model(|cx| ActiveCall::new(client, user_store, cx));
cx.set_global(active_call);
}
pub struct ActiveCall {
room: Option<(ModelHandle<Room>, Vec<Subscription>)>,
+ incoming_call: (
+ watch::Sender<Option<IncomingCall>>,
+ watch::Receiver<Option<IncomingCall>>,
+ ),
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
+ _subscriptions: Vec<client::Subscription>,
}
impl Entity for ActiveCall {
@@ -25,14 +34,63 @@ impl Entity for ActiveCall {
}
impl ActiveCall {
- fn new(client: Arc<Client>, user_store: ModelHandle<UserStore>) -> Self {
+ fn new(
+ client: Arc<Client>,
+ user_store: ModelHandle<UserStore>,
+ cx: &mut ModelContext<Self>,
+ ) -> Self {
Self {
room: None,
+ incoming_call: watch::channel(),
+ _subscriptions: vec![
+ client.add_request_handler(cx.handle(), Self::handle_incoming_call),
+ client.add_message_handler(cx.handle(), Self::handle_cancel_call),
+ ],
client,
user_store,
}
}
+ async fn handle_incoming_call(
+ this: ModelHandle<Self>,
+ envelope: TypedEnvelope<proto::IncomingCall>,
+ _: Arc<Client>,
+ mut cx: AsyncAppContext,
+ ) -> Result<proto::Ack> {
+ let user_store = this.read_with(&cx, |this, _| this.user_store.clone());
+ let call = IncomingCall {
+ room_id: envelope.payload.room_id,
+ participants: user_store
+ .update(&mut cx, |user_store, cx| {
+ user_store.get_users(envelope.payload.participant_user_ids, cx)
+ })
+ .await?,
+ caller: user_store
+ .update(&mut cx, |user_store, cx| {
+ user_store.get_user(envelope.payload.caller_user_id, cx)
+ })
+ .await?,
+ initial_project_id: envelope.payload.initial_project_id,
+ };
+ this.update(&mut cx, |this, _| {
+ *this.incoming_call.0.borrow_mut() = Some(call);
+ });
+
+ Ok(proto::Ack {})
+ }
+
+ async fn handle_cancel_call(
+ this: ModelHandle<Self>,
+ _: TypedEnvelope<proto::CancelCall>,
+ _: Arc<Client>,
+ mut cx: AsyncAppContext,
+ ) -> Result<()> {
+ this.update(&mut cx, |this, _| {
+ *this.incoming_call.0.borrow_mut() = None;
+ });
+ Ok(())
+ }
+
pub fn global(cx: &AppContext) -> ModelHandle<Self> {
cx.global::<ModelHandle<Self>>().clone()
}
@@ -74,12 +132,22 @@ impl ActiveCall {
})
}
- pub fn join(&mut self, call: &IncomingCall, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
+ pub fn incoming(&self) -> watch::Receiver<Option<IncomingCall>> {
+ self.incoming_call.1.clone()
+ }
+
+ pub fn accept_incoming(&mut self, 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, self.client.clone(), self.user_store.clone(), cx);
+ let call = if let Some(call) = self.incoming_call.1.borrow().clone() {
+ call
+ } else {
+ return Task::ready(Err(anyhow!("no incoming call")));
+ };
+
+ 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.set_room(Some(room.clone()), cx));
@@ -87,6 +155,19 @@ impl ActiveCall {
})
}
+ pub fn decline_incoming(&mut self) -> Result<()> {
+ *self.incoming_call.0.borrow_mut() = None;
+ self.client.send(proto::DeclineCall {})?;
+ Ok(())
+ }
+
+ pub fn hang_up(&mut self, cx: &mut ModelContext<Self>) -> Result<()> {
+ if let Some((room, _)) = self.room.take() {
+ room.update(cx, |room, cx| room.leave(cx))?;
+ }
+ Ok(())
+ }
+
fn set_room(&mut self, room: Option<ModelHandle<Room>>, cx: &mut ModelContext<Self>) {
if room.as_ref() != self.room.as_ref().map(|room| &room.0) {
if let Some(room) = room {
@@ -66,7 +66,7 @@ impl Room {
}
}
- pub fn create(
+ pub(crate) fn create(
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
cx: &mut MutableAppContext,
@@ -77,7 +77,7 @@ impl Room {
})
}
- pub fn join(
+ pub(crate) fn join(
call: &IncomingCall,
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
@@ -93,7 +93,7 @@ impl Room {
})
}
- pub fn leave(&mut self, cx: &mut ModelContext<Self>) -> Result<()> {
+ pub(crate) fn leave(&mut self, cx: &mut ModelContext<Self>) -> Result<()> {
if self.status.is_offline() {
return Err(anyhow!("room is offline"));
}
@@ -213,7 +213,7 @@ impl Room {
Ok(())
}
- pub fn call(
+ pub(crate) fn call(
&mut self,
recipient_user_id: u64,
initial_project_id: Option<u64>,
@@ -1,5 +1,4 @@
use super::{http::HttpClient, proto, Client, Status, TypedEnvelope};
-use crate::incoming_call::IncomingCall;
use anyhow::{anyhow, Context, Result};
use collections::{hash_map::Entry, HashMap, HashSet};
use futures::{channel::mpsc, future, AsyncReadExt, Future, StreamExt};
@@ -59,10 +58,6 @@ pub struct UserStore {
outgoing_contact_requests: Vec<Arc<User>>,
pending_contact_requests: HashMap<u64, usize>,
invite_info: Option<InviteInfo>,
- incoming_call: (
- watch::Sender<Option<IncomingCall>>,
- watch::Receiver<Option<IncomingCall>>,
- ),
client: Weak<Client>,
http: Arc<dyn HttpClient>,
_maintain_contacts: Task<()>,
@@ -112,8 +107,6 @@ impl UserStore {
client.add_message_handler(cx.handle(), Self::handle_update_contacts),
client.add_message_handler(cx.handle(), Self::handle_update_invite_info),
client.add_message_handler(cx.handle(), Self::handle_show_contacts),
- client.add_request_handler(cx.handle(), Self::handle_incoming_call),
- client.add_message_handler(cx.handle(), Self::handle_cancel_call),
];
Self {
users: Default::default(),
@@ -122,7 +115,6 @@ impl UserStore {
incoming_contact_requests: Default::default(),
outgoing_contact_requests: Default::default(),
invite_info: None,
- incoming_call: watch::channel(),
client: Arc::downgrade(&client),
update_contacts_tx,
http,
@@ -194,60 +186,10 @@ impl UserStore {
Ok(())
}
- async fn handle_incoming_call(
- this: ModelHandle<Self>,
- envelope: TypedEnvelope<proto::IncomingCall>,
- _: Arc<Client>,
- mut cx: AsyncAppContext,
- ) -> Result<proto::Ack> {
- let call = IncomingCall {
- room_id: envelope.payload.room_id,
- participants: this
- .update(&mut cx, |this, cx| {
- this.get_users(envelope.payload.participant_user_ids, cx)
- })
- .await?,
- caller: this
- .update(&mut cx, |this, cx| {
- this.get_user(envelope.payload.caller_user_id, cx)
- })
- .await?,
- initial_project_id: envelope.payload.initial_project_id,
- };
- this.update(&mut cx, |this, _| {
- *this.incoming_call.0.borrow_mut() = Some(call);
- });
-
- Ok(proto::Ack {})
- }
-
- async fn handle_cancel_call(
- this: ModelHandle<Self>,
- _: TypedEnvelope<proto::CancelCall>,
- _: Arc<Client>,
- mut cx: AsyncAppContext,
- ) -> Result<()> {
- this.update(&mut cx, |this, _| {
- *this.incoming_call.0.borrow_mut() = None;
- });
- Ok(())
- }
-
pub fn invite_info(&self) -> Option<&InviteInfo> {
self.invite_info.as_ref()
}
- pub fn incoming_call(&self) -> watch::Receiver<Option<IncomingCall>> {
- self.incoming_call.1.clone()
- }
-
- pub fn decline_call(&mut self) -> Result<()> {
- if let Some(client) = self.client.upgrade() {
- client.send(proto::DeclineCall {})?;
- }
- Ok(())
- }
-
async fn handle_update_contacts(
this: ModelHandle<Self>,
message: TypedEnvelope<proto::UpdateContacts>,
@@ -5,7 +5,7 @@ use crate::{
};
use ::rpc::Peer;
use anyhow::anyhow;
-use call::{room, ParticipantLocation, Room};
+use call::{room, ActiveCall, ParticipantLocation, Room};
use client::{
self, test::FakeHttpClient, Channel, ChannelDetails, ChannelList, Client, Connection,
Credentials, EstablishConnectionError, User, UserStore, RECEIVE_TIMEOUT,
@@ -78,29 +78,18 @@ async fn test_basic_calls(
.make_contacts(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
.await;
- let room_a = cx_a
- .update(|cx| Room::create(client_a.clone(), client_a.user_store.clone(), cx))
- .await
- .unwrap();
- assert_eq!(
- room_participants(&room_a, cx_a),
- RoomParticipants {
- remote: Default::default(),
- pending: Default::default()
- }
- );
+ let active_call_a = cx_a.read(ActiveCall::global);
+ let active_call_b = cx_b.read(ActiveCall::global);
+ let active_call_c = cx_c.read(ActiveCall::global);
// Call user B from client A.
- let mut incoming_call_b = client_b
- .user_store
- .update(cx_b, |user, _| user.incoming_call());
- room_a
- .update(cx_a, |room, cx| {
- room.call(client_b.user_id().unwrap(), None, cx)
+ active_call_a
+ .update(cx_a, |call, cx| {
+ call.invite(client_b.user_id().unwrap(), None, cx)
})
.await
.unwrap();
-
+ let room_a = active_call_a.read_with(cx_a, |call, _| call.room().unwrap().clone());
deterministic.run_until_parked();
assert_eq!(
room_participants(&room_a, cx_a),
@@ -111,21 +100,24 @@ async fn test_basic_calls(
);
// User B receives the call.
+ let mut incoming_call_b = active_call_b.read_with(cx_b, |call, _| call.incoming());
let call_b = incoming_call_b.next().await.unwrap().unwrap();
+ assert_eq!(call_b.caller.github_login, "user_a");
// User B connects via another client and also receives a ring on the newly-connected client.
- let client_b2 = server.create_client(cx_b2, "user_b").await;
- let mut incoming_call_b2 = client_b2
- .user_store
- .update(cx_b2, |user, _| user.incoming_call());
+ let _client_b2 = server.create_client(cx_b2, "user_b").await;
+ let active_call_b2 = cx_b2.read(ActiveCall::global);
+ let mut incoming_call_b2 = active_call_b2.read_with(cx_b2, |call, _| call.incoming());
deterministic.run_until_parked();
- let _call_b2 = incoming_call_b2.next().await.unwrap().unwrap();
+ let call_b2 = incoming_call_b2.next().await.unwrap().unwrap();
+ assert_eq!(call_b2.caller.github_login, "user_a");
// User B joins the room using the first client.
- let room_b = cx_b
- .update(|cx| Room::join(&call_b, client_b.clone(), client_b.user_store.clone(), cx))
+ active_call_b
+ .update(cx_b, |call, cx| call.accept_incoming(cx))
.await
.unwrap();
+ let room_b = active_call_b.read_with(cx_b, |call, _| call.room().unwrap().clone());
assert!(incoming_call_b.next().await.unwrap().is_none());
deterministic.run_until_parked();
@@ -145,12 +137,10 @@ async fn test_basic_calls(
);
// Call user C from client B.
- let mut incoming_call_c = client_c
- .user_store
- .update(cx_c, |user, _| user.incoming_call());
- room_b
- .update(cx_b, |room, cx| {
- room.call(client_c.user_id().unwrap(), None, cx)
+ let mut incoming_call_c = active_call_c.read_with(cx_c, |call, _| call.incoming());
+ active_call_b
+ .update(cx_b, |call, cx| {
+ call.invite(client_c.user_id().unwrap(), None, cx)
})
.await
.unwrap();
@@ -172,11 +162,9 @@ async fn test_basic_calls(
);
// User C receives the call, but declines it.
- let _call_c = incoming_call_c.next().await.unwrap().unwrap();
- client_c
- .user_store
- .update(cx_c, |user, _| user.decline_call())
- .unwrap();
+ let call_c = incoming_call_c.next().await.unwrap().unwrap();
+ assert_eq!(call_c.caller.github_login, "user_b");
+ active_call_c.update(cx_c, |call, _| call.decline_incoming().unwrap());
assert!(incoming_call_c.next().await.unwrap().is_none());
deterministic.run_until_parked();
@@ -196,7 +184,10 @@ async fn test_basic_calls(
);
// User A leaves the room.
- room_a.update(cx_a, |room, cx| room.leave(cx)).unwrap();
+ active_call_a.update(cx_a, |call, cx| {
+ call.hang_up(cx).unwrap();
+ assert!(call.room().is_none());
+ });
deterministic.run_until_parked();
assert_eq!(
room_participants(&room_a, cx_a),
@@ -218,108 +209,107 @@ async fn test_basic_calls(
async fn test_room_uniqueness(
deterministic: Arc<Deterministic>,
cx_a: &mut TestAppContext,
+ cx_a2: &mut TestAppContext,
cx_b: &mut TestAppContext,
+ cx_b2: &mut TestAppContext,
cx_c: &mut TestAppContext,
) {
deterministic.forbid_parking();
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
+ let _client_a2 = server.create_client(cx_a2, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
+ let _client_b2 = server.create_client(cx_b2, "user_b").await;
let client_c = server.create_client(cx_c, "user_c").await;
server
.make_contacts(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
.await;
- let room_a = cx_a
- .update(|cx| Room::create(client_a.clone(), client_a.user_store.clone(), cx))
- .await
- .unwrap();
- // Ensure room can't be created given we've just created one.
- cx_a.update(|cx| Room::create(client_a.clone(), client_a.user_store.clone(), cx))
- .await
- .unwrap_err();
+ let active_call_a = cx_a.read(ActiveCall::global);
+ let active_call_a2 = cx_a2.read(ActiveCall::global);
+ let active_call_b = cx_b.read(ActiveCall::global);
+ let active_call_b2 = cx_b2.read(ActiveCall::global);
+ let active_call_c = cx_c.read(ActiveCall::global);
// Call user B from client A.
- let mut incoming_call_b = client_b
- .user_store
- .update(cx_b, |user, _| user.incoming_call());
- room_a
- .update(cx_a, |room, cx| {
- room.call(client_b.user_id().unwrap(), None, cx)
+ active_call_a
+ .update(cx_a, |call, cx| {
+ call.invite(client_b.user_id().unwrap(), None, cx)
})
.await
.unwrap();
+
+ // Ensure a new room can't be created given user A just created one.
+ active_call_a2
+ .update(cx_a2, |call, cx| {
+ call.invite(client_c.user_id().unwrap(), None, cx)
+ })
+ .await
+ .unwrap_err();
+ active_call_a2.read_with(cx_a2, |call, _| assert!(call.room().is_none()));
+
+ // User B receives the call from user A.
+ let mut incoming_call_b = active_call_b.read_with(cx_b, |call, _| call.incoming());
let call_b1 = incoming_call_b.next().await.unwrap().unwrap();
assert_eq!(call_b1.caller.github_login, "user_a");
// Ensure calling users A and B from client C fails.
- let room_c = cx_c
- .update(|cx| Room::create(client_c.clone(), client_c.user_store.clone(), cx))
- .await
- .unwrap();
- room_c
- .update(cx_c, |room, cx| {
- room.call(client_a.user_id().unwrap(), None, cx)
+ active_call_c
+ .update(cx_c, |call, cx| {
+ call.invite(client_a.user_id().unwrap(), None, cx)
})
.await
.unwrap_err();
- room_c
- .update(cx_c, |room, cx| {
- room.call(client_b.user_id().unwrap(), None, cx)
+ active_call_c
+ .update(cx_c, |call, cx| {
+ call.invite(client_b.user_id().unwrap(), None, cx)
})
.await
.unwrap_err();
// Ensure User B can't create a room while they still have an incoming call.
- cx_b.update(|cx| Room::create(client_b.clone(), client_b.user_store.clone(), cx))
+ active_call_b2
+ .update(cx_b2, |call, cx| {
+ call.invite(client_c.user_id().unwrap(), None, cx)
+ })
.await
.unwrap_err();
+ active_call_b2.read_with(cx_b2, |call, _| assert!(call.room().is_none()));
// User B joins the room and calling them after they've joined still fails.
- let room_b = cx_b
- .update(|cx| {
- Room::join(
- &call_b1,
- client_b.client.clone(),
- client_b.user_store.clone(),
- cx,
- )
- })
+ active_call_b
+ .update(cx_b, |call, cx| call.accept_incoming(cx))
.await
.unwrap();
- room_c
- .update(cx_c, |room, cx| {
- room.call(client_b.user_id().unwrap(), None, cx)
+ active_call_c
+ .update(cx_c, |call, cx| {
+ call.invite(client_b.user_id().unwrap(), None, cx)
})
.await
.unwrap_err();
// Ensure User B can't create a room while they belong to another room.
- cx_b.update(|cx| Room::create(client_b.clone(), client_b.user_store.clone(), cx))
+ active_call_b2
+ .update(cx_b2, |call, cx| {
+ call.invite(client_c.user_id().unwrap(), None, cx)
+ })
.await
.unwrap_err();
+ active_call_b2.read_with(cx_b2, |call, _| assert!(call.room().is_none()));
// Client C can successfully call client B after client B leaves the room.
- cx_b.update(|_| drop(room_b));
+ active_call_b
+ .update(cx_b, |call, cx| call.hang_up(cx))
+ .unwrap();
deterministic.run_until_parked();
- room_c
- .update(cx_c, |room, cx| {
- room.call(client_b.user_id().unwrap(), None, cx)
+ active_call_c
+ .update(cx_c, |call, cx| {
+ call.invite(client_b.user_id().unwrap(), None, cx)
})
.await
.unwrap();
let call_b2 = incoming_call_b.next().await.unwrap().unwrap();
assert_eq!(call_b2.caller.github_login, "user_c");
-
- // Client B can successfully create a room after declining the call from client C.
- client_b
- .user_store
- .update(cx_b, |user_store, _| user_store.decline_call())
- .unwrap();
- deterministic.run_until_parked();
- cx_b.update(|cx| Room::create(client_b.clone(), client_b.user_store.clone(), cx))
- .await
- .unwrap();
}
#[gpui::test(iterations = 10)]
@@ -336,28 +326,26 @@ async fn test_leaving_room_on_disconnection(
.make_contacts(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
- let room_a = cx_a
- .update(|cx| Room::create(client_a.clone(), client_a.user_store.clone(), cx))
- .await
- .unwrap();
+ let active_call_a = cx_a.read(ActiveCall::global);
+ let active_call_b = cx_b.read(ActiveCall::global);
// Call user B from client A.
- let mut incoming_call_b = client_b
- .user_store
- .update(cx_b, |user, _| user.incoming_call());
- room_a
- .update(cx_a, |room, cx| {
- room.call(client_b.user_id().unwrap(), None, cx)
+ active_call_a
+ .update(cx_a, |call, cx| {
+ call.invite(client_b.user_id().unwrap(), None, cx)
})
.await
.unwrap();
+ let room_a = active_call_a.read_with(cx_a, |call, _| call.room().unwrap().clone());
// User B receives the call and joins the room.
- let call_b = incoming_call_b.next().await.unwrap().unwrap();
- let room_b = cx_b
- .update(|cx| Room::join(&call_b, client_b.clone(), client_b.user_store.clone(), cx))
+ let mut incoming_call_b = active_call_b.read_with(cx_b, |call, _| call.incoming());
+ incoming_call_b.next().await.unwrap().unwrap();
+ active_call_b
+ .update(cx_b, |call, cx| call.accept_incoming(cx))
.await
.unwrap();
+ let room_b = active_call_b.read_with(cx_b, |call, _| call.room().unwrap().clone());
deterministic.run_until_parked();
assert_eq!(
room_participants(&room_a, cx_a),
@@ -398,13 +386,13 @@ async fn test_share_project(
cx_a: &mut TestAppContext,
cx_b: &mut TestAppContext,
) {
- cx_a.foreground().forbid_parking();
+ deterministic.forbid_parking();
let (_, window_b) = cx_b.add_window(|_| EmptyView);
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -502,10 +490,13 @@ async fn test_unshare_project(
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
let client_c = server.create_client(cx_c, "user_c").await;
- let (room_id, mut rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
.await;
+ let active_call_a = cx_a.read(ActiveCall::global);
+ let active_call_b = cx_b.read(ActiveCall::global);
+
client_a
.fs
.insert_tree(
@@ -532,7 +523,7 @@ async fn test_unshare_project(
.unwrap();
// When client B leaves the room, the project becomes read-only.
- cx_b.update(|_| drop(rooms.remove(1)));
+ active_call_b.update(cx_b, |call, cx| call.hang_up(cx).unwrap());
deterministic.run_until_parked();
assert!(project_b.read_with(cx_b, |project, _| project.is_read_only()));
@@ -560,7 +551,7 @@ async fn test_unshare_project(
.unwrap();
// When client A (the host) leaves the room, the project gets unshared and guests are notified.
- cx_a.update(|_| drop(rooms.remove(0)));
+ active_call_a.update(cx_a, |call, cx| call.hang_up(cx).unwrap());
deterministic.run_until_parked();
project_a.read_with(cx_a, |project, _| assert!(!project.is_shared()));
project_c2.read_with(cx_c, |project, _| {
@@ -582,8 +573,8 @@ async fn test_host_disconnect(
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
let client_c = server.create_client(cx_c, "user_c").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
.await;
client_a
@@ -660,7 +651,7 @@ async fn test_host_disconnect(
}
#[gpui::test(iterations = 10)]
-async fn test_room_events(
+async fn test_active_call_events(
deterministic: Arc<Deterministic>,
cx_a: &mut TestAppContext,
cx_b: &mut TestAppContext,
@@ -675,24 +666,21 @@ async fn test_room_events(
let (project_a, _) = client_a.build_local_project("/a", cx_a).await;
let (project_b, _) = client_b.build_local_project("/b", cx_b).await;
- let (room_id, mut rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
- let room_a = rooms.remove(0);
- let room_a_events = room_events(&room_a, cx_a);
-
- let room_b = rooms.remove(0);
- let room_b_events = room_events(&room_b, cx_b);
+ let events_a = active_call_events(cx_a);
+ let events_b = active_call_events(cx_b);
let project_a_id = project_a
.update(cx_a, |project, cx| project.share(room_id, cx))
.await
.unwrap();
deterministic.run_until_parked();
- assert_eq!(mem::take(&mut *room_a_events.borrow_mut()), vec![]);
+ assert_eq!(mem::take(&mut *events_a.borrow_mut()), vec![]);
assert_eq!(
- mem::take(&mut *room_b_events.borrow_mut()),
+ mem::take(&mut *events_b.borrow_mut()),
vec![room::Event::RemoteProjectShared {
owner: Arc::new(User {
id: client_a.user_id().unwrap(),
@@ -709,7 +697,7 @@ async fn test_room_events(
.unwrap();
deterministic.run_until_parked();
assert_eq!(
- mem::take(&mut *room_a_events.borrow_mut()),
+ mem::take(&mut *events_a.borrow_mut()),
vec![room::Event::RemoteProjectShared {
owner: Arc::new(User {
id: client_b.user_id().unwrap(),
@@ -719,17 +707,15 @@ async fn test_room_events(
project_id: project_b_id,
}]
);
- assert_eq!(mem::take(&mut *room_b_events.borrow_mut()), vec![]);
+ assert_eq!(mem::take(&mut *events_b.borrow_mut()), vec![]);
- fn room_events(
- room: &ModelHandle<Room>,
- cx: &mut TestAppContext,
- ) -> Rc<RefCell<Vec<room::Event>>> {
+ fn active_call_events(cx: &mut TestAppContext) -> Rc<RefCell<Vec<room::Event>>> {
let events = Rc::new(RefCell::new(Vec::new()));
+ let active_call = cx.read(ActiveCall::global);
cx.update({
let events = events.clone();
|cx| {
- cx.subscribe(room, move |_, event, _| {
+ cx.subscribe(&active_call, move |_, event, _| {
events.borrow_mut().push(event.clone())
})
.detach()
@@ -755,26 +741,28 @@ async fn test_room_location(
let (project_a, _) = client_a.build_local_project("/a", cx_a).await;
let (project_b, _) = client_b.build_local_project("/b", cx_b).await;
- let (room_id, mut rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
- let room_a = rooms.remove(0);
- let room_a_notified = Rc::new(Cell::new(false));
+ let active_call_a = cx_a.read(ActiveCall::global);
+ let room_a = active_call_a.read_with(cx_a, |call, _| call.room().unwrap().clone());
+ let a_notified = Rc::new(Cell::new(false));
cx_a.update({
- let room_a_notified = room_a_notified.clone();
+ let notified = a_notified.clone();
|cx| {
- cx.observe(&room_a, move |_, _| room_a_notified.set(true))
+ cx.observe(&active_call_a, move |_, _| notified.set(true))
.detach()
}
});
- let room_b = rooms.remove(0);
- let room_b_notified = Rc::new(Cell::new(false));
+ let active_call_b = cx_b.read(ActiveCall::global);
+ let room_b = active_call_b.read_with(cx_b, |call, _| call.room().unwrap().clone());
+ let b_notified = Rc::new(Cell::new(false));
cx_b.update({
- let room_b_notified = room_b_notified.clone();
+ let b_notified = b_notified.clone();
|cx| {
- cx.observe(&room_b, move |_, _| room_b_notified.set(true))
+ cx.observe(&active_call_b, move |_, _| b_notified.set(true))
.detach()
}
});
@@ -784,12 +772,12 @@ async fn test_room_location(
.await
.unwrap();
deterministic.run_until_parked();
- assert!(room_a_notified.take());
+ assert!(a_notified.take());
assert_eq!(
participant_locations(&room_a, cx_a),
vec![("user_b".to_string(), ParticipantLocation::External)]
);
- assert!(room_b_notified.take());
+ assert!(b_notified.take());
assert_eq!(
participant_locations(&room_b, cx_b),
vec![("user_a".to_string(), ParticipantLocation::External)]
@@ -800,12 +788,12 @@ async fn test_room_location(
.await
.unwrap();
deterministic.run_until_parked();
- assert!(room_a_notified.take());
+ assert!(a_notified.take());
assert_eq!(
participant_locations(&room_a, cx_a),
vec![("user_b".to_string(), ParticipantLocation::External)]
);
- assert!(room_b_notified.take());
+ assert!(b_notified.take());
assert_eq!(
participant_locations(&room_b, cx_b),
vec![("user_a".to_string(), ParticipantLocation::External)]
@@ -816,12 +804,12 @@ async fn test_room_location(
.await
.unwrap();
deterministic.run_until_parked();
- assert!(room_a_notified.take());
+ assert!(a_notified.take());
assert_eq!(
participant_locations(&room_a, cx_a),
vec![("user_b".to_string(), ParticipantLocation::External)]
);
- assert!(room_b_notified.take());
+ assert!(b_notified.take());
assert_eq!(
participant_locations(&room_b, cx_b),
vec![(
@@ -837,7 +825,7 @@ async fn test_room_location(
.await
.unwrap();
deterministic.run_until_parked();
- assert!(room_a_notified.take());
+ assert!(a_notified.take());
assert_eq!(
participant_locations(&room_a, cx_a),
vec![(
@@ -847,7 +835,7 @@ async fn test_room_location(
}
)]
);
- assert!(room_b_notified.take());
+ assert!(b_notified.take());
assert_eq!(
participant_locations(&room_b, cx_b),
vec![(
@@ -863,12 +851,12 @@ async fn test_room_location(
.await
.unwrap();
deterministic.run_until_parked();
- assert!(room_a_notified.take());
+ assert!(a_notified.take());
assert_eq!(
participant_locations(&room_a, cx_a),
vec![("user_b".to_string(), ParticipantLocation::External)]
);
- assert!(room_b_notified.take());
+ assert!(b_notified.take());
assert_eq!(
participant_locations(&room_b, cx_b),
vec![(
@@ -908,8 +896,8 @@ async fn test_propagate_saves_and_fs_changes(
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
let client_c = server.create_client(cx_c, "user_c").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
.await;
client_a
@@ -1056,8 +1044,8 @@ async fn test_fs_operations(
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -1321,8 +1309,8 @@ async fn test_buffer_conflict_after_save(cx_a: &mut TestAppContext, cx_b: &mut T
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -1374,8 +1362,8 @@ async fn test_buffer_reloading(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -1432,8 +1420,8 @@ async fn test_editing_while_guest_opens_buffer(
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -1478,8 +1466,8 @@ async fn test_leaving_worktree_while_opening_buffer(
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -1522,8 +1510,8 @@ async fn test_canceling_buffer_opening(
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -1573,8 +1561,8 @@ async fn test_leaving_project(
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
let client_c = server.create_client(cx_c, "user_c").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
.await;
client_a
@@ -1663,8 +1651,8 @@ async fn test_collaborating_with_diagnostics(
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
let client_c = server.create_client(cx_c, "user_c").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
.await;
// Set up a fake language server.
@@ -1900,8 +1888,8 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -2073,8 +2061,8 @@ async fn test_reloading_buffer_manually(cx_a: &mut TestAppContext, cx_b: &mut Te
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -2165,8 +2153,8 @@ async fn test_formatting_buffer(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -2265,8 +2253,8 @@ async fn test_definition(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -2408,8 +2396,8 @@ async fn test_references(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -2508,8 +2496,8 @@ async fn test_project_search(cx_a: &mut TestAppContext, cx_b: &mut TestAppContex
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -2586,8 +2574,8 @@ async fn test_document_highlights(cx_a: &mut TestAppContext, cx_b: &mut TestAppC
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -2687,8 +2675,8 @@ async fn test_lsp_hover(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
client_a
@@ -2789,8 +2777,8 @@ async fn test_project_symbols(cx_a: &mut TestAppContext, cx_b: &mut TestAppConte
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -2896,8 +2884,8 @@ async fn test_open_buffer_while_getting_definition_pointing_to_it(
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -2971,8 +2959,8 @@ async fn test_collaborating_with_code_actions(
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -3181,8 +3169,8 @@ async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut T
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -3372,8 +3360,8 @@ async fn test_language_server_statuses(
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
// Set up a fake language server.
@@ -4145,8 +4133,8 @@ async fn test_following(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
cx_a.update(editor::init);
cx_b.update(editor::init);
@@ -4354,8 +4342,8 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
cx_a.update(editor::init);
cx_b.update(editor::init);
@@ -4522,8 +4510,8 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
cx_a.update(editor::init);
cx_b.update(editor::init);
@@ -4685,8 +4673,8 @@ async fn test_peers_simultaneously_following_each_other(
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
- let (room_id, _rooms) = server
- .create_rooms(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ let room_id = server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
cx_a.update(editor::init);
cx_b.update(editor::init);
@@ -4790,12 +4778,8 @@ async fn test_random_collaboration(
.unwrap();
}
- let client = server.create_client(cx, "room-creator").await;
- let room = cx
- .update(|cx| Room::create(client.client.clone(), client.user_store.clone(), cx))
- .await
- .unwrap();
- let room_id = room.read_with(cx, |room, _| room.id());
+ let _room_creator = server.create_client(cx, "room-creator").await;
+ let active_call = cx.read(ActiveCall::global);
let mut clients = Vec::new();
let mut user_ids = Vec::new();
@@ -4963,22 +4947,17 @@ async fn test_random_collaboration(
host_language_registry.add(Arc::new(language));
let host_user_id = host.current_user_id(&host_cx);
- room.update(cx, |room, cx| room.call(host_user_id.to_proto(), None, cx))
+ active_call
+ .update(cx, |call, cx| {
+ call.invite(host_user_id.to_proto(), None, cx)
+ })
.await
.unwrap();
+ let room_id = active_call.read_with(cx, |call, cx| call.room().unwrap().read(cx).id());
deterministic.run_until_parked();
- let call = host
- .user_store
- .read_with(&host_cx, |user_store, _| user_store.incoming_call());
- let host_room = host_cx
- .update(|cx| {
- Room::join(
- call.borrow().as_ref().unwrap(),
- host.client.clone(),
- host.user_store.clone(),
- cx,
- )
- })
+ host_cx
+ .read(ActiveCall::global)
+ .update(&mut host_cx, |call, cx| call.accept_incoming(cx))
.await
.unwrap();
@@ -4991,7 +4970,6 @@ async fn test_random_collaboration(
user_ids.push(host_user_id);
op_start_signals.push(op_start_signal.0);
clients.push(host_cx.foreground().spawn(host.simulate_host(
- host_room,
host_project,
op_start_signal.1,
rng.clone(),
@@ -5016,20 +4994,26 @@ async fn test_random_collaboration(
deterministic.finish_waiting();
deterministic.run_until_parked();
- let (host, host_room, host_project, mut host_cx, host_err) = clients.remove(0);
+ let (host, host_project, mut host_cx, host_err) = clients.remove(0);
if let Some(host_err) = host_err {
log::error!("host error - {:?}", host_err);
}
host_project.read_with(&host_cx, |project, _| assert!(!project.is_shared()));
- for (guest, guest_room, guest_project, mut guest_cx, guest_err) in clients {
+ for (guest, guest_project, mut guest_cx, guest_err) in clients {
if let Some(guest_err) = guest_err {
log::error!("{} error - {:?}", guest.username, guest_err);
}
guest_project.read_with(&guest_cx, |project, _| assert!(project.is_read_only()));
- guest_cx.update(|_| drop((guest, guest_room, guest_project)));
+ guest_cx.update(|cx| {
+ cx.clear_globals();
+ drop((guest, guest_project));
+ });
}
- host_cx.update(|_| drop((host, host_room, host_project)));
+ host_cx.update(|cx| {
+ cx.clear_globals();
+ drop((host, host_project));
+ });
return;
}
@@ -5055,23 +5039,16 @@ async fn test_random_collaboration(
let guest = server.create_client(&mut guest_cx, &guest_username).await;
let guest_user_id = guest.current_user_id(&guest_cx);
- room.update(cx, |room, cx| room.call(guest_user_id.to_proto(), None, cx))
+ active_call
+ .update(cx, |call, cx| {
+ call.invite(guest_user_id.to_proto(), None, cx)
+ })
.await
.unwrap();
deterministic.run_until_parked();
- let call = guest
- .user_store
- .read_with(&guest_cx, |user_store, _| user_store.incoming_call());
-
- let guest_room = guest_cx
- .update(|cx| {
- Room::join(
- call.borrow().as_ref().unwrap(),
- guest.client.clone(),
- guest.user_store.clone(),
- cx,
- )
- })
+ guest_cx
+ .read(ActiveCall::global)
+ .update(&mut guest_cx, |call, cx| call.accept_incoming(cx))
.await
.unwrap();
@@ -5093,7 +5070,6 @@ async fn test_random_collaboration(
op_start_signals.push(op_start_signal.0);
clients.push(guest_cx.foreground().spawn(guest.simulate_guest(
guest_username.clone(),
- guest_room,
guest_project,
op_start_signal.1,
rng.clone(),
@@ -5114,7 +5090,7 @@ async fn test_random_collaboration(
deterministic.advance_clock(RECEIVE_TIMEOUT);
deterministic.start_waiting();
log::info!("Waiting for guest {} to exit...", removed_guest_id);
- let (guest, guest_room, guest_project, mut guest_cx, guest_err) = guest.await;
+ let (guest, guest_project, mut guest_cx, guest_err) = guest.await;
deterministic.finish_waiting();
server.allow_connections();
@@ -5142,7 +5118,10 @@ async fn test_random_collaboration(
log::info!("{} removed", guest.username);
available_guests.push(guest.username.clone());
- guest_cx.update(|_| drop((guest, guest_room, guest_project)));
+ guest_cx.update(|cx| {
+ cx.clear_globals();
+ drop((guest, guest_project));
+ });
operations += 1;
}
@@ -13,7 +13,7 @@ use workspace::{AppState, JoinProject, ToggleFollow, Workspace};
pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
contacts_popover::init(cx);
collab_titlebar_item::init(cx);
- incoming_call_notification::init(app_state.user_store.clone(), cx);
+ incoming_call_notification::init(cx);
project_shared_notification::init(cx);
cx.add_global_action(move |action: &JoinProject, cx| {
@@ -1,11 +1,11 @@
use call::ActiveCall;
-use client::{incoming_call::IncomingCall, UserStore};
+use client::incoming_call::IncomingCall;
use futures::StreamExt;
use gpui::{
elements::*,
geometry::{rect::RectF, vector::vec2f},
- impl_internal_actions, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext,
- View, ViewContext, WindowBounds, WindowKind, WindowOptions,
+ impl_internal_actions, Entity, MouseButton, MutableAppContext, RenderContext, View,
+ ViewContext, WindowBounds, WindowKind, WindowOptions,
};
use settings::Settings;
use util::ResultExt;
@@ -13,10 +13,10 @@ use workspace::JoinProject;
impl_internal_actions!(incoming_call_notification, [RespondToCall]);
-pub fn init(user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
+pub fn init(cx: &mut MutableAppContext) {
cx.add_action(IncomingCallNotification::respond_to_call);
- let mut incoming_call = user_store.read(cx).incoming_call();
+ let mut incoming_call = ActiveCall::global(cx).read(cx).incoming();
cx.spawn(|mut cx| async move {
let mut notification_window = None;
while let Some(incoming_call) = incoming_call.next().await {
@@ -33,7 +33,7 @@ pub fn init(user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
kind: WindowKind::PopUp,
is_movable: false,
},
- |_| IncomingCallNotification::new(incoming_call, user_store.clone()),
+ |_| IncomingCallNotification::new(incoming_call),
);
notification_window = Some(window_id);
}
@@ -49,18 +49,17 @@ struct RespondToCall {
pub struct IncomingCallNotification {
call: IncomingCall,
- user_store: ModelHandle<UserStore>,
}
impl IncomingCallNotification {
- pub fn new(call: IncomingCall, user_store: ModelHandle<UserStore>) -> Self {
- Self { call, user_store }
+ pub fn new(call: IncomingCall) -> Self {
+ Self { call }
}
fn respond_to_call(&mut self, action: &RespondToCall, cx: &mut ViewContext<Self>) {
+ let active_call = ActiveCall::global(cx);
if action.accept {
- let join = ActiveCall::global(cx)
- .update(cx, |active_call, cx| active_call.join(&self.call, cx));
+ let join = active_call.update(cx, |active_call, cx| active_call.accept_incoming(cx));
let caller_user_id = self.call.caller.id;
let initial_project_id = self.call.initial_project_id;
cx.spawn_weak(|_, mut cx| async move {
@@ -77,12 +76,10 @@ impl IncomingCallNotification {
})
.detach_and_log_err(cx);
} else {
- self.user_store
- .update(cx, |user_store, _| user_store.decline_call().log_err());
+ active_call.update(cx, |active_call, _| {
+ active_call.decline_incoming().log_err();
+ });
}
-
- let window_id = cx.window_id();
- cx.remove_window(window_id);
}
fn render_caller(&self, cx: &mut RenderContext<Self>) -> ElementBox {
@@ -1906,6 +1906,10 @@ impl MutableAppContext {
})
}
+ pub fn clear_globals(&mut self) {
+ self.cx.globals.clear();
+ }
+
pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
where
T: Entity,
@@ -91,7 +91,7 @@ pub fn run_test(
cx.update(|cx| cx.remove_all_windows());
deterministic.run_until_parked();
- cx.update(|_| {}); // flush effects
+ cx.update(|cx| cx.clear_globals());
leak_detector.lock().detect();
if is_last_iteration {
@@ -122,7 +122,7 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
cx_teardowns.extend(quote!(
#cx_varname.update(|cx| cx.remove_all_windows());
deterministic.run_until_parked();
- #cx_varname.update(|_| {}); // flush effects
+ #cx_varname.update(|cx| cx.clear_globals());
));
inner_fn_args.extend(quote!(&mut #cx_varname,));
continue;