From b4531235efb974b6ce9126a937e320092e77c897 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 2 May 2023 11:53:24 +0200 Subject: [PATCH] Merge pull request #2430 from zed-industries/fix-toggle-contacts-panic Fix panic when showing contacts popover via keybinding --- crates/collab_ui/src/collab_titlebar_item.rs | 100 +++++++++---------- crates/workspace/src/workspace.rs | 2 +- crates/zed/src/zed.rs | 2 +- 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index 7a9c2cd97e284dab3a49ee832a857a05f9235218..1534ade80c22798bd320c8e470f2abc8463d619f 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -4,7 +4,7 @@ use crate::{ ToggleScreenSharing, }; use call::{ActiveCall, ParticipantLocation, Room}; -use client::{proto::PeerId, ContactEventKind, SignIn, SignOut, User, UserStore}; +use client::{proto::PeerId, Client, ContactEventKind, SignIn, SignOut, User, UserStore}; use clock::ReplicaId; use contacts_popover::ContactsPopover; use context_menu::{ContextMenu, ContextMenuItem}; @@ -19,6 +19,7 @@ use gpui::{ AppContext, Entity, ImageData, ModelHandle, SceneBuilder, Subscription, View, ViewContext, ViewHandle, WeakViewHandle, }; +use project::Project; use settings::Settings; use std::{ops::Range, sync::Arc}; use theme::{AvatarStyle, Theme}; @@ -51,8 +52,10 @@ pub fn init(cx: &mut AppContext) { } pub struct CollabTitlebarItem { - workspace: WeakViewHandle, + project: ModelHandle, user_store: ModelHandle, + client: Arc, + workspace: WeakViewHandle, contacts_popover: Option>, user_menu: ViewHandle, collaborator_list_popover: Option>, @@ -75,7 +78,7 @@ impl View for CollabTitlebarItem { return Empty::new().into_any(); }; - let project = workspace.read(cx).project().read(cx); + let project = self.project.read(cx); let mut project_title = String::new(); for (i, name) in project.worktree_root_names(cx).enumerate() { if i > 0 { @@ -100,8 +103,8 @@ impl View for CollabTitlebarItem { .left(), ); - let user = workspace.read(cx).user_store().read(cx).current_user(); - let peer_id = workspace.read(cx).client().peer_id(); + let user = self.user_store.read(cx).current_user(); + let peer_id = self.client.peer_id(); if let Some(((user, peer_id), room)) = user .zip(peer_id) .zip(ActiveCall::global(cx).read(cx).room().cloned()) @@ -135,20 +138,23 @@ impl View for CollabTitlebarItem { impl CollabTitlebarItem { pub fn new( - workspace: &ViewHandle, - user_store: &ModelHandle, + workspace: &Workspace, + workspace_handle: &ViewHandle, cx: &mut ViewContext, ) -> Self { + let project = workspace.project().clone(); + let user_store = workspace.user_store().clone(); + let client = workspace.client().clone(); let active_call = ActiveCall::global(cx); let mut subscriptions = Vec::new(); - subscriptions.push(cx.observe(workspace, |_, _, cx| cx.notify())); + subscriptions.push(cx.observe(workspace_handle, |_, _, cx| cx.notify())); subscriptions.push(cx.observe(&active_call, |this, _, cx| this.active_call_changed(cx))); subscriptions.push(cx.observe_window_activation(|this, active, cx| { this.window_activation_changed(active, cx) })); - subscriptions.push(cx.observe(user_store, |_, _, cx| cx.notify())); + subscriptions.push(cx.observe(&user_store, |_, _, cx| cx.notify())); subscriptions.push( - cx.subscribe(user_store, move |this, user_store, event, cx| { + cx.subscribe(&user_store, move |this, user_store, event, cx| { if let Some(workspace) = this.workspace.upgrade(cx) { workspace.update(cx, |workspace, cx| { if let client::Event::Contact { user, kind } = event { @@ -171,8 +177,10 @@ impl CollabTitlebarItem { ); Self { - workspace: workspace.downgrade(), - user_store: user_store.clone(), + workspace: workspace.weak_handle(), + project, + user_store, + client, contacts_popover: None, user_menu: cx.add_view(|cx| { let mut menu = ContextMenu::new(cx); @@ -185,16 +193,14 @@ impl CollabTitlebarItem { } fn window_activation_changed(&mut self, active: bool, cx: &mut ViewContext) { - if let Some(workspace) = self.workspace.upgrade(cx) { - let project = if active { - Some(workspace.read(cx).project().clone()) - } else { - None - }; - ActiveCall::global(cx) - .update(cx, |call, cx| call.set_location(project.as_ref(), cx)) - .detach_and_log_err(cx); - } + let project = if active { + Some(self.project.clone()) + } else { + None + }; + ActiveCall::global(cx) + .update(cx, |call, cx| call.set_location(project.as_ref(), cx)) + .detach_and_log_err(cx); } fn active_call_changed(&mut self, cx: &mut ViewContext) { @@ -205,23 +211,19 @@ impl CollabTitlebarItem { } fn share_project(&mut self, _: &ShareProject, cx: &mut ViewContext) { - if let Some(workspace) = self.workspace.upgrade(cx) { - let active_call = ActiveCall::global(cx); - let project = workspace.read(cx).project().clone(); - active_call - .update(cx, |call, cx| call.share_project(project, cx)) - .detach_and_log_err(cx); - } + let active_call = ActiveCall::global(cx); + let project = self.project.clone(); + active_call + .update(cx, |call, cx| call.share_project(project, cx)) + .detach_and_log_err(cx); } fn unshare_project(&mut self, _: &UnshareProject, cx: &mut ViewContext) { - if let Some(workspace) = self.workspace.upgrade(cx) { - let active_call = ActiveCall::global(cx); - let project = workspace.read(cx).project().clone(); - active_call - .update(cx, |call, cx| call.unshare_project(project, cx)) - .log_err(); - } + let active_call = ActiveCall::global(cx); + let project = self.project.clone(); + active_call + .update(cx, |call, cx| call.unshare_project(project, cx)) + .log_err(); } pub fn toggle_collaborator_list_popover( @@ -256,22 +258,20 @@ impl CollabTitlebarItem { pub fn toggle_contacts_popover(&mut self, _: &ToggleContactsMenu, cx: &mut ViewContext) { if self.contacts_popover.take().is_none() { - if let Some(workspace) = self.workspace.upgrade(cx) { - let project = workspace.read(cx).project().clone(); - let user_store = workspace.read(cx).user_store().clone(); - let view = cx.add_view(|cx| ContactsPopover::new(project, user_store, cx)); - cx.subscribe(&view, |this, _, event, cx| { - match event { - contacts_popover::Event::Dismissed => { - this.contacts_popover = None; - } + let view = cx.add_view(|cx| { + ContactsPopover::new(self.project.clone(), self.user_store.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(); + }) + .detach(); + self.contacts_popover = Some(view); } cx.notify(); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 7524b84bf8f92b853142a3469d3b94a445f6ca09..26afa544773e1f1d08023c73e0e315223288e096 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1044,7 +1044,7 @@ impl Workspace { &self.project } - pub fn client(&self) -> &Client { + pub fn client(&self) -> &Arc { &self.client } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 446a493692df638a4a96af19d490bbf98178a9f1..d0ce4118b4f0688b9786b8e70c014ac7e4eb344b 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -309,7 +309,7 @@ pub fn initialize_workspace( cx.emit(workspace::Event::PaneAdded(workspace.dock_pane().clone())); let collab_titlebar_item = - cx.add_view(|cx| CollabTitlebarItem::new(&workspace_handle, &app_state.user_store, cx)); + cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx)); workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx); let project_panel = ProjectPanel::new(workspace.project().clone(), cx);