Send LeaveProject when waiting room is dismissed while waiting

This commit is contained in:
Antonio Scandurra 2022-05-17 11:10:56 +02:00
parent d821e7a4c1
commit cc598a6f71
3 changed files with 82 additions and 54 deletions

View file

@ -133,8 +133,12 @@ impl ContactsPanel {
if let Some(workspace) = workspace.upgrade(cx) { if let Some(workspace) = workspace.upgrade(cx) {
workspace.update(cx, |workspace, cx| { workspace.update(cx, |workspace, cx| {
workspace.show_notification( workspace.show_notification(
cx.add_view(|_| { cx.add_view(|cx| {
JoinProjectNotification::new(project, user.clone()) JoinProjectNotification::new(
project,
user.clone(),
cx,
)
}), }),
cx, cx,
) )

View file

@ -25,7 +25,15 @@ pub struct JoinProjectNotification {
} }
impl JoinProjectNotification { impl JoinProjectNotification {
pub fn new(project: ModelHandle<Project>, user: Arc<User>) -> Self { pub fn new(project: ModelHandle<Project>, user: Arc<User>, cx: &mut ViewContext<Self>) -> Self {
cx.subscribe(&project, |this, _, event, cx| {
if let project::Event::ContactCancelledJoinRequest(user) = event {
if *user == this.user {
cx.emit(Event::Dismiss);
}
}
})
.detach();
Self { project, user } Self { project, user }
} }

View file

@ -3,25 +3,35 @@ use crate::{
AppState, AppState,
}; };
use anyhow::Result; use anyhow::Result;
use client::Contact; use client::{proto, Client, Contact};
use gpui::{elements::*, ElementBox, Entity, ImageData, RenderContext, Task, View, ViewContext}; use gpui::{
elements::*, ElementBox, Entity, ImageData, MutableAppContext, RenderContext, Task, View,
ViewContext,
};
use project::Project; use project::Project;
use settings::Settings; use settings::Settings;
use std::sync::Arc; use std::sync::Arc;
use util::ResultExt;
pub struct WaitingRoom { pub struct WaitingRoom {
project_id: u64,
avatar: Option<Arc<ImageData>>, avatar: Option<Arc<ImageData>>,
message: String, message: String,
joined: bool, waiting: bool,
client: Arc<Client>,
_join_task: Task<Result<()>>, _join_task: Task<Result<()>>,
} }
impl Entity for WaitingRoom { impl Entity for WaitingRoom {
type Event = (); type Event = ();
fn release(&mut self, _: &mut gpui::MutableAppContext) { fn release(&mut self, _: &mut MutableAppContext) {
if !self.joined { if self.waiting {
// TODO: Cancel the join request self.client
.send(proto::LeaveProject {
project_id: self.project_id,
})
.log_err();
} }
} }
} }
@ -66,7 +76,7 @@ impl WaitingRoom {
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Self { ) -> Self {
let project_id = contact.projects[project_index].id; let project_id = contact.projects[project_index].id;
let client = app_state.client.clone();
let _join_task = cx.spawn_weak({ let _join_task = cx.spawn_weak({
let contact = contact.clone(); let contact = contact.clone();
|this, mut cx| async move { |this, mut cx| async move {
@ -81,47 +91,50 @@ impl WaitingRoom {
.await; .await;
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, cx| match project { this.update(&mut cx, |this, cx| {
Ok(project) => { this.waiting = false;
this.joined = true; match project {
cx.replace_root_view(|cx| { Ok(project) => {
let mut workspace = cx.replace_root_view(|cx| {
(app_state.build_workspace)(project, &app_state, cx); let mut workspace =
workspace.toggle_sidebar_item( (app_state.build_workspace)(project, &app_state, cx);
&ToggleSidebarItem { workspace.toggle_sidebar_item(
side: Side::Left, &ToggleSidebarItem {
item_index: 0, side: Side::Left,
}, item_index: 0,
cx, },
); cx,
workspace );
}); workspace
} });
Err(error @ _) => { }
let login = &contact.user.github_login; Err(error @ _) => {
let message = match error { let login = &contact.user.github_login;
project::JoinProjectError::HostDeclined => { let message = match error {
format!("@{} declined your request.", login) project::JoinProjectError::HostDeclined => {
} format!("@{} declined your request.", login)
project::JoinProjectError::HostClosedProject => { }
format!( project::JoinProjectError::HostClosedProject => {
"@{} closed their copy of {}.", format!(
login, "@{} closed their copy of {}.",
humanize_list( login,
&contact.projects[project_index].worktree_root_names humanize_list(
&contact.projects[project_index]
.worktree_root_names
)
) )
) }
} project::JoinProjectError::HostWentOffline => {
project::JoinProjectError::HostWentOffline => { format!("@{} went offline.", login)
format!("@{} went offline.", login) }
} project::JoinProjectError::Other(error) => {
project::JoinProjectError::Other(error) => { log::error!("error joining project: {}", error);
log::error!("error joining project: {}", error); "An error occurred.".to_string()
"An error occurred.".to_string() }
} };
}; this.message = message;
this.message = message; cx.notify();
cx.notify(); }
} }
}) })
} }
@ -131,13 +144,15 @@ impl WaitingRoom {
}); });
Self { Self {
project_id,
avatar: contact.user.avatar.clone(), avatar: contact.user.avatar.clone(),
message: format!( message: format!(
"Asking to join @{}'s copy of {}...", "Asking to join @{}'s copy of {}...",
contact.user.github_login, contact.user.github_login,
humanize_list(&contact.projects[project_index].worktree_root_names) humanize_list(&contact.projects[project_index].worktree_root_names)
), ),
joined: false, waiting: true,
client,
_join_task, _join_task,
} }
} }
@ -149,10 +164,11 @@ fn humanize_list<'a>(items: impl IntoIterator<Item = &'a String>) -> String {
while let Some((ix, item)) = items.next() { while let Some((ix, item)) = items.next() {
if ix > 0 { if ix > 0 {
list.push_str(", "); list.push_str(", ");
if items.peek().is_none() {
list.push_str("and ");
}
} }
if items.peek().is_none() {
list.push_str("and ");
}
list.push_str(item); list.push_str(item);
} }
list list