diff --git a/crates/call/src/call.rs b/crates/call/src/call.rs index d800c3ac0657fbbe716ef1f1799b4e75b9d7adbd..19de06c1c40dd98f98badecdd7cf1fc186eb1b82 100644 --- a/crates/call/src/call.rs +++ b/crates/call/src/call.rs @@ -3,7 +3,7 @@ pub mod room; use anyhow::{anyhow, Result}; use client::{incoming_call::IncomingCall, Client, UserStore}; -use gpui::{Entity, ModelContext, ModelHandle, MutableAppContext, Task}; +use gpui::{Entity, ModelContext, ModelHandle, MutableAppContext, Subscription, Task}; pub use participant::ParticipantLocation; pub use room::Room; use std::sync::Arc; @@ -14,13 +14,13 @@ pub fn init(client: Arc, user_store: ModelHandle, cx: &mut Mu } pub struct ActiveCall { - room: Option>, + room: Option<(ModelHandle, Vec)>, client: Arc, user_store: ModelHandle, } impl Entity for ActiveCall { - type Event = (); + type Event = room::Event; } impl ActiveCall { @@ -41,8 +41,7 @@ impl ActiveCall { recipient_user_id: u64, cx: &mut ModelContext, ) -> Task> { - let room = self.room.clone(); - + let room = self.room.as_ref().map(|(room, _)| room.clone()); let client = self.client.clone(); let user_store = self.user_store.clone(); cx.spawn(|this, mut cx| async move { @@ -50,10 +49,7 @@ impl ActiveCall { 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(); - }); + this.update(&mut cx, |this, cx| this.set_room(Some(room.clone()), cx)); room }; room.update(&mut cx, |room, cx| room.call(recipient_user_id, cx)) @@ -71,15 +67,25 @@ impl ActiveCall { 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); - cx.notify(); - }); + this.update(&mut cx, |this, cx| this.set_room(Some(room.clone()), cx)); Ok(()) }) } + fn set_room(&mut self, room: Option>, cx: &mut ModelContext) { + if let Some(room) = room { + let subscriptions = vec![ + cx.observe(&room, |_, _, cx| cx.notify()), + cx.subscribe(&room, |_, _, event, cx| cx.emit(event.clone())), + ]; + self.room = Some((room, subscriptions)); + } else { + self.room = None; + } + cx.notify(); + } + pub fn room(&self) -> Option<&ModelHandle> { - self.room.as_ref() + self.room.as_ref().map(|(room, _)| room) } } diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index a30ae68f9feaf07516a97c2a47cd5fedda393f2b..81ec7973a5b139bc4040c2fbd4f4d4cdbc599b70 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -30,7 +30,6 @@ pub fn init(cx: &mut MutableAppContext) { pub struct CollabTitlebarItem { workspace: WeakViewHandle, contacts_popover: Option>, - room_subscription: Option, _subscriptions: Vec, } @@ -73,24 +72,12 @@ impl CollabTitlebarItem { let active_call = ActiveCall::global(cx); let mut subscriptions = Vec::new(); subscriptions.push(cx.observe(workspace, |_, _, cx| cx.notify())); - subscriptions.push(cx.observe(&active_call, |this, _, cx| this.active_call_changed(cx))); - let mut this = Self { + subscriptions.push(cx.observe(&active_call, |_, _, cx| cx.notify())); + Self { workspace: workspace.downgrade(), contacts_popover: None, - room_subscription: None, _subscriptions: subscriptions, - }; - this.active_call_changed(cx); - this - } - - fn active_call_changed(&mut self, cx: &mut ViewContext) { - if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() { - self.room_subscription = Some(cx.observe(&room, |_, _, cx| cx.notify())); - } else { - self.room_subscription = None; } - cx.notify(); } fn share_project(&mut self, _: &ShareProject, cx: &mut ViewContext) { diff --git a/crates/collab_ui/src/contacts_popover.rs b/crates/collab_ui/src/contacts_popover.rs index 742096104130f7cbb5aed3ed0f1465d102b1986b..1980d8a14fc4f3174d93f396177f440e969acf58 100644 --- a/crates/collab_ui/src/contacts_popover.rs +++ b/crates/collab_ui/src/contacts_popover.rs @@ -80,7 +80,6 @@ pub enum Event { } pub struct ContactsPopover { - room_subscription: Option, entries: Vec, match_candidates: Vec, list_state: ListState, @@ -159,10 +158,9 @@ impl ContactsPopover { let active_call = ActiveCall::global(cx); let mut subscriptions = Vec::new(); subscriptions.push(cx.observe(&user_store, |this, _, cx| this.update_entries(cx))); - subscriptions.push(cx.observe(&active_call, |this, _, cx| this.active_call_changed(cx))); + subscriptions.push(cx.observe(&active_call, |_, _, cx| cx.notify())); let mut this = Self { - room_subscription: None, list_state, selection: None, collapsed_sections: Default::default(), @@ -173,19 +171,9 @@ impl ContactsPopover { user_store, }; this.update_entries(cx); - this.active_call_changed(cx); this } - fn active_call_changed(&mut self, cx: &mut ViewContext) { - if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() { - self.room_subscription = Some(cx.observe(&room, |_, _, cx| cx.notify())); - } else { - self.room_subscription = None; - } - cx.notify(); - } - fn clear_filter(&mut self, _: &Cancel, cx: &mut ViewContext) { let did_clear = self.filter_editor.update(cx, |editor, cx| { if editor.buffer().read(cx).len(cx) > 0 { diff --git a/crates/collab_ui/src/project_shared_notification.rs b/crates/collab_ui/src/project_shared_notification.rs index 879c3ca28cbcf2dae621d031b08ce5568bc88248..53eb17684e9a0f53aecbf03efc201b9c5099768c 100644 --- a/crates/collab_ui/src/project_shared_notification.rs +++ b/crates/collab_ui/src/project_shared_notification.rs @@ -19,35 +19,18 @@ pub fn init(app_state: Arc, cx: &mut MutableAppContext) { cx.add_action(ProjectSharedNotification::dismiss); let active_call = ActiveCall::global(cx); - let mut _room_subscription = None; - cx.observe(&active_call, move |active_call, cx| { - if let Some(room) = active_call.read(cx).room().cloned() { - let app_state = app_state.clone(); - _room_subscription = Some(cx.subscribe(&room, move |_, event, cx| match event { - room::Event::RemoteProjectShared { owner, project_id } => { - cx.add_window( - WindowOptions { - bounds: WindowBounds::Fixed(RectF::new( - vec2f(0., 0.), - vec2f(300., 400.), - )), - titlebar: None, - center: true, - kind: WindowKind::PopUp, - is_movable: false, - }, - |_| { - ProjectSharedNotification::new( - *project_id, - owner.clone(), - app_state.clone(), - ) - }, - ); - } - })); - } else { - _room_subscription = None; + cx.subscribe(&active_call, move |_, event, cx| match event { + room::Event::RemoteProjectShared { owner, project_id } => { + cx.add_window( + WindowOptions { + bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(300., 400.))), + titlebar: None, + center: true, + kind: WindowKind::PopUp, + is_movable: false, + }, + |_| ProjectSharedNotification::new(*project_id, owner.clone(), app_state.clone()), + ); } }) .detach();