Ensure notifications are dismissed
Before this change if you joined a project without clicking on the notification it would never disappear. Fix a related bug where if you have more than one monitor, the notification was only dismissed from one of them.
This commit is contained in:
parent
9dc292772a
commit
39af2bb0a4
6 changed files with 61 additions and 21 deletions
|
@ -44,6 +44,12 @@ pub enum Event {
|
||||||
RemoteProjectUnshared {
|
RemoteProjectUnshared {
|
||||||
project_id: u64,
|
project_id: u64,
|
||||||
},
|
},
|
||||||
|
RemoteProjectJoined {
|
||||||
|
project_id: u64,
|
||||||
|
},
|
||||||
|
RemoteProjectInvitationDiscarded {
|
||||||
|
project_id: u64,
|
||||||
|
},
|
||||||
Left,
|
Left,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,6 +1021,7 @@ impl Room {
|
||||||
) -> Task<Result<ModelHandle<Project>>> {
|
) -> Task<Result<ModelHandle<Project>>> {
|
||||||
let client = self.client.clone();
|
let client = self.client.clone();
|
||||||
let user_store = self.user_store.clone();
|
let user_store = self.user_store.clone();
|
||||||
|
cx.emit(Event::RemoteProjectJoined { project_id: id });
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
let project =
|
let project =
|
||||||
Project::remote(id, client, user_store, language_registry, fs, cx.clone()).await?;
|
Project::remote(id, client, user_store, language_registry, fs, cx.clone()).await?;
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
use crate::{rpc::RECONNECT_TIMEOUT, tests::TestServer};
|
use crate::{rpc::RECONNECT_TIMEOUT, tests::TestServer};
|
||||||
use call::ActiveCall;
|
use call::ActiveCall;
|
||||||
|
use collab_ui::project_shared_notification::ProjectSharedNotification;
|
||||||
use editor::{Editor, ExcerptRange, MultiBuffer};
|
use editor::{Editor, ExcerptRange, MultiBuffer};
|
||||||
use gpui::{executor::Deterministic, geometry::vector::vec2f, TestAppContext, ViewHandle};
|
use gpui::{
|
||||||
|
executor::Deterministic, geometry::vector::vec2f, AppContext, TestAppContext, ViewHandle,
|
||||||
|
};
|
||||||
use live_kit_client::MacOSDisplay;
|
use live_kit_client::MacOSDisplay;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -1073,6 +1076,24 @@ async fn test_peers_simultaneously_following_each_other(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visible_push_notifications(
|
||||||
|
cx: &mut TestAppContext,
|
||||||
|
) -> Vec<gpui::ViewHandle<ProjectSharedNotification>> {
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
for window in cx.windows() {
|
||||||
|
window.read_with(cx, |window| {
|
||||||
|
if let Some(handle) = window
|
||||||
|
.root_view()
|
||||||
|
.clone()
|
||||||
|
.downcast::<ProjectSharedNotification>()
|
||||||
|
{
|
||||||
|
ret.push(handle)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 10)]
|
#[gpui::test(iterations = 10)]
|
||||||
async fn test_following_across_workspaces(
|
async fn test_following_across_workspaces(
|
||||||
deterministic: Arc<Deterministic>,
|
deterministic: Arc<Deterministic>,
|
||||||
|
@ -1126,17 +1147,22 @@ async fn test_following_across_workspaces(
|
||||||
let (project_a, worktree_id_a) = client_a.build_local_project("/a", cx_a).await;
|
let (project_a, worktree_id_a) = client_a.build_local_project("/a", cx_a).await;
|
||||||
let (project_b, worktree_id_b) = client_b.build_local_project("/b", cx_b).await;
|
let (project_b, worktree_id_b) = client_b.build_local_project("/b", cx_b).await;
|
||||||
|
|
||||||
|
let workspace_a = client_a.build_workspace(&project_a, cx_a).root(cx_a);
|
||||||
|
let workspace_b = client_b.build_workspace(&project_b, cx_b).root(cx_b);
|
||||||
|
|
||||||
|
cx_a.update(|cx| collab_ui::init(&client_a.app_state, cx));
|
||||||
|
cx_b.update(|cx| collab_ui::init(&client_b.app_state, cx));
|
||||||
|
|
||||||
let project_a_id = active_call_a
|
let project_a_id = active_call_a
|
||||||
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
|
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
/*
|
||||||
let project_b_id = active_call_b
|
let project_b_id = active_call_b
|
||||||
.update(cx_b, |call, cx| call.share_project(project_b.clone(), cx))
|
.update(cx_b, |call, cx| call.share_project(project_b.clone(), cx))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
*/
|
||||||
let workspace_a = client_a.build_workspace(&project_a, cx_a).root(cx_a);
|
|
||||||
let workspace_b = client_b.build_workspace(&project_b, cx_b).root(cx_b);
|
|
||||||
|
|
||||||
active_call_a
|
active_call_a
|
||||||
.update(cx_a, |call, cx| call.set_location(Some(&project_a), cx))
|
.update(cx_a, |call, cx| call.set_location(Some(&project_a), cx))
|
||||||
|
@ -1157,7 +1183,9 @@ async fn test_following_across_workspaces(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
deterministic.run_until_parked();
|
deterministic.run_until_parked();
|
||||||
assert_eq!(cx_b.windows().len(), 1);
|
assert_eq!(cx_b.windows().len(), 2);
|
||||||
|
|
||||||
|
assert_eq!(visible_push_notifications(cx_b).len(), 1);
|
||||||
|
|
||||||
workspace_b.update(cx_b, |workspace, cx| {
|
workspace_b.update(cx_b, |workspace, cx| {
|
||||||
workspace
|
workspace
|
||||||
|
@ -1186,4 +1214,5 @@ async fn test_following_across_workspaces(
|
||||||
});
|
});
|
||||||
|
|
||||||
// assert that there are no share notifications open
|
// assert that there are no share notifications open
|
||||||
|
assert_eq!(visible_push_notifications(cx_b).len(), 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -948,7 +948,7 @@ impl CollabTitlebarItem {
|
||||||
fn render_face_pile(
|
fn render_face_pile(
|
||||||
&self,
|
&self,
|
||||||
user: &User,
|
user: &User,
|
||||||
replica_id: Option<ReplicaId>,
|
_replica_id: Option<ReplicaId>,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
location: Option<ParticipantLocation>,
|
location: Option<ParticipantLocation>,
|
||||||
muted: bool,
|
muted: bool,
|
||||||
|
|
|
@ -7,7 +7,7 @@ mod face_pile;
|
||||||
mod incoming_call_notification;
|
mod incoming_call_notification;
|
||||||
mod notifications;
|
mod notifications;
|
||||||
mod panel_settings;
|
mod panel_settings;
|
||||||
mod project_shared_notification;
|
pub mod project_shared_notification;
|
||||||
mod sharing_status_indicator;
|
mod sharing_status_indicator;
|
||||||
|
|
||||||
use call::{report_call_event_for_room, ActiveCall, Room};
|
use call::{report_call_event_for_room, ActiveCall, Room};
|
||||||
|
|
|
@ -40,7 +40,8 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
||||||
.push(window);
|
.push(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
room::Event::RemoteProjectUnshared { project_id } => {
|
room::Event::RemoteProjectUnshared { project_id }
|
||||||
|
| room::Event::RemoteProjectInvitationDiscarded { project_id } => {
|
||||||
if let Some(windows) = notification_windows.remove(&project_id) {
|
if let Some(windows) = notification_windows.remove(&project_id) {
|
||||||
for window in windows {
|
for window in windows {
|
||||||
window.remove(cx);
|
window.remove(cx);
|
||||||
|
@ -54,6 +55,13 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
room::Event::RemoteProjectJoined { project_id } => {
|
||||||
|
if let Some(windows) = notification_windows.remove(&project_id) {
|
||||||
|
for window in windows {
|
||||||
|
window.remove(cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
@ -82,7 +90,6 @@ impl ProjectSharedNotification {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join(&mut self, cx: &mut ViewContext<Self>) {
|
fn join(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
cx.remove_window();
|
|
||||||
if let Some(app_state) = self.app_state.upgrade() {
|
if let Some(app_state) = self.app_state.upgrade() {
|
||||||
workspace::join_remote_project(self.project_id, self.owner.id, app_state, cx)
|
workspace::join_remote_project(self.project_id, self.owner.id, app_state, cx)
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
|
@ -90,7 +97,15 @@ impl ProjectSharedNotification {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dismiss(&mut self, cx: &mut ViewContext<Self>) {
|
fn dismiss(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
cx.remove_window();
|
if let Some(active_room) =
|
||||||
|
ActiveCall::global(cx).read_with(cx, |call, _| call.room().cloned())
|
||||||
|
{
|
||||||
|
active_room.update(cx, |_, cx| {
|
||||||
|
cx.emit(room::Event::RemoteProjectInvitationDiscarded {
|
||||||
|
project_id: self.project_id,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_owner(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
fn render_owner(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||||
|
|
|
@ -2529,7 +2529,6 @@ impl Workspace {
|
||||||
|
|
||||||
if let Some(prev_leader_id) = self.unfollow(&pane, cx) {
|
if let Some(prev_leader_id) = self.unfollow(&pane, cx) {
|
||||||
if leader_id == prev_leader_id {
|
if leader_id == prev_leader_id {
|
||||||
dbg!("oh no!");
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2618,7 +2617,6 @@ impl Workspace {
|
||||||
let project = self.project.read(cx);
|
let project = self.project.read(cx);
|
||||||
|
|
||||||
let Some(remote_participant) = room.remote_participant_for_peer_id(leader_id) else {
|
let Some(remote_participant) = room.remote_participant_for_peer_id(leader_id) else {
|
||||||
dbg!("no remote participant yet...");
|
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2633,7 +2631,6 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
dbg!(other_project_id);
|
|
||||||
|
|
||||||
// if they are active in another project, follow there.
|
// if they are active in another project, follow there.
|
||||||
if let Some(project_id) = other_project_id {
|
if let Some(project_id) = other_project_id {
|
||||||
|
@ -2650,7 +2647,6 @@ impl Workspace {
|
||||||
for (existing_leader_id, states_by_pane) in &mut self.follower_states_by_leader {
|
for (existing_leader_id, states_by_pane) in &mut self.follower_states_by_leader {
|
||||||
if leader_id == *existing_leader_id {
|
if leader_id == *existing_leader_id {
|
||||||
for (pane, _) in states_by_pane {
|
for (pane, _) in states_by_pane {
|
||||||
dbg!("focusing pane");
|
|
||||||
cx.focus(pane);
|
cx.focus(pane);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -4249,7 +4245,6 @@ pub fn join_remote_project(
|
||||||
app_state: Arc<AppState>,
|
app_state: Arc<AppState>,
|
||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
dbg!("huh??");
|
|
||||||
cx.spawn(|mut cx| async move {
|
cx.spawn(|mut cx| async move {
|
||||||
let existing_workspace = cx
|
let existing_workspace = cx
|
||||||
.windows()
|
.windows()
|
||||||
|
@ -4268,10 +4263,8 @@ pub fn join_remote_project(
|
||||||
.flatten();
|
.flatten();
|
||||||
|
|
||||||
let workspace = if let Some(existing_workspace) = existing_workspace {
|
let workspace = if let Some(existing_workspace) = existing_workspace {
|
||||||
dbg!("huh");
|
|
||||||
existing_workspace
|
existing_workspace
|
||||||
} else {
|
} else {
|
||||||
dbg!("huh/");
|
|
||||||
let active_call = cx.read(ActiveCall::global);
|
let active_call = cx.read(ActiveCall::global);
|
||||||
let room = active_call
|
let room = active_call
|
||||||
.read_with(&cx, |call, _| call.room().cloned())
|
.read_with(&cx, |call, _| call.room().cloned())
|
||||||
|
@ -4287,7 +4280,6 @@ pub fn join_remote_project(
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
dbg!("huh//");
|
|
||||||
let window_bounds_override = window_bounds_env_override(&cx);
|
let window_bounds_override = window_bounds_env_override(&cx);
|
||||||
let window = cx.add_window(
|
let window = cx.add_window(
|
||||||
(app_state.build_window_options)(
|
(app_state.build_window_options)(
|
||||||
|
@ -4310,7 +4302,6 @@ pub fn join_remote_project(
|
||||||
workspace.downgrade()
|
workspace.downgrade()
|
||||||
};
|
};
|
||||||
|
|
||||||
dbg!("huh///");
|
|
||||||
workspace.window().activate(&mut cx);
|
workspace.window().activate(&mut cx);
|
||||||
cx.platform().activate(true);
|
cx.platform().activate(true);
|
||||||
|
|
||||||
|
@ -4333,8 +4324,6 @@ pub fn join_remote_project(
|
||||||
Some(collaborator.peer_id)
|
Some(collaborator.peer_id)
|
||||||
});
|
});
|
||||||
|
|
||||||
dbg!(follow_peer_id);
|
|
||||||
|
|
||||||
if let Some(follow_peer_id) = follow_peer_id {
|
if let Some(follow_peer_id) = follow_peer_id {
|
||||||
workspace
|
workspace
|
||||||
.follow(follow_peer_id, cx)
|
.follow(follow_peer_id, cx)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue