Allow following into channel notes regardless of project

This commit is contained in:
Max Brunsfeld
2023-09-21 17:12:59 -07:00
parent ed8b022b51
commit 4ffa167256
10 changed files with 201 additions and 114 deletions
+6
View File
@@ -696,6 +696,7 @@ pub trait FollowableItem: Item {
message: proto::update_view::Variant,
cx: &mut ViewContext<Self>,
) -> Task<Result<()>>;
fn is_project_item(&self, cx: &AppContext) -> bool;
fn set_leader_replica_id(&mut self, leader_replica_id: Option<u16>, cx: &mut ViewContext<Self>);
fn should_unfollow_on_event(event: &Self::Event, cx: &AppContext) -> bool;
@@ -718,6 +719,7 @@ pub trait FollowableItemHandle: ItemHandle {
cx: &mut WindowContext,
) -> Task<Result<()>>;
fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool;
fn is_project_item(&self, cx: &AppContext) -> bool;
}
impl<T: FollowableItem> FollowableItemHandle for ViewHandle<T> {
@@ -769,6 +771,10 @@ impl<T: FollowableItem> FollowableItemHandle for ViewHandle<T> {
false
}
}
fn is_project_item(&self, cx: &AppContext) -> bool {
self.read(cx).is_project_item(cx)
}
}
#[cfg(any(test, feature = "test-support"))]
+8 -11
View File
@@ -210,7 +210,6 @@ impl Member {
} else {
let leader_user = leader.user.clone();
let leader_user_id = leader.user.id;
let app_state = Arc::downgrade(app_state);
Some(
MouseEventHandler::new::<FollowIntoExternalProject, _>(
pane.id(),
@@ -234,16 +233,14 @@ impl Member {
},
)
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, move |_, _, cx| {
if let Some(app_state) = app_state.upgrade() {
crate::join_remote_project(
leader_project_id,
leader_user_id,
app_state,
cx,
)
.detach_and_log_err(cx);
}
.on_click(MouseButton::Left, move |_, this, cx| {
crate::join_remote_project(
leader_project_id,
leader_user_id,
this.app_state().clone(),
cx,
)
.detach_and_log_err(cx);
})
.aligned()
.bottom()
+35 -27
View File
@@ -2832,14 +2832,12 @@ impl Workspace {
.read_with(cx, |this, _| this.project.clone())
.ok_or_else(|| anyhow!("window dropped"))?;
let replica_id = project
.read_with(cx, |project, _| {
project
.collaborators()
.get(&leader_id)
.map(|c| c.replica_id)
})
.ok_or_else(|| anyhow!("no such collaborator {}", leader_id))?;
let replica_id = project.read_with(cx, |project, _| {
project
.collaborators()
.get(&leader_id)
.map(|c| c.replica_id)
});
let item_builders = cx.update(|cx| {
cx.default_global::<FollowableItemBuilders>()
@@ -2884,7 +2882,7 @@ impl Workspace {
.get_mut(&pane)?;
for (id, item) in leader_view_ids.into_iter().zip(items) {
item.set_leader_replica_id(Some(replica_id), cx);
item.set_leader_replica_id(replica_id, cx);
state.items_by_leader_view_id.insert(id, item);
}
@@ -2947,30 +2945,40 @@ impl Workspace {
let room = call.read(cx).room()?.read(cx);
let participant = room.remote_participant_for_peer_id(leader_id)?;
let mut items_to_activate = Vec::new();
let leader_in_this_app;
let leader_in_this_project;
match participant.location {
call::ParticipantLocation::SharedProject { project_id } => {
if Some(project_id) == self.project.read(cx).remote_id() {
for (pane, state) in self.follower_states_by_leader.get(&leader_id)? {
if let Some(item) = state
.active_view_id
.and_then(|id| state.items_by_leader_view_id.get(&id))
{
items_to_activate.push((pane.clone(), item.boxed_clone()));
} else if let Some(shared_screen) =
self.shared_screen_for_peer(leader_id, pane, cx)
{
items_to_activate.push((pane.clone(), Box::new(shared_screen)));
}
}
}
leader_in_this_app = true;
leader_in_this_project = Some(project_id) == self.project.read(cx).remote_id();
}
call::ParticipantLocation::UnsharedProject => {
leader_in_this_app = true;
leader_in_this_project = false;
}
call::ParticipantLocation::UnsharedProject => {}
call::ParticipantLocation::External => {
for (pane, _) in self.follower_states_by_leader.get(&leader_id)? {
if let Some(shared_screen) = self.shared_screen_for_peer(leader_id, pane, cx) {
items_to_activate.push((pane.clone(), Box::new(shared_screen)));
leader_in_this_app = false;
leader_in_this_project = false;
}
};
for (pane, state) in self.follower_states_by_leader.get(&leader_id)? {
let item = state
.active_view_id
.and_then(|id| state.items_by_leader_view_id.get(&id));
let shared_screen = self.shared_screen_for_peer(leader_id, pane, cx);
if leader_in_this_app {
if let Some(item) = item {
if leader_in_this_project || !item.is_project_item(cx) {
items_to_activate.push((pane.clone(), item.boxed_clone()));
}
} else if let Some(shared_screen) = shared_screen {
items_to_activate.push((pane.clone(), Box::new(shared_screen)));
}
} else if let Some(shared_screen) = shared_screen {
items_to_activate.push((pane.clone(), Box::new(shared_screen)));
}
}