collab_ui.rs

  1mod collab_titlebar_item;
  2mod contact_finder;
  3mod contact_list;
  4mod contact_notification;
  5mod contacts_popover;
  6mod incoming_call_notification;
  7mod notifications;
  8mod project_shared_notification;
  9
 10use call::ActiveCall;
 11pub use collab_titlebar_item::{CollabTitlebarItem, ToggleCollaborationMenu};
 12use gpui::MutableAppContext;
 13use project::Project;
 14use std::sync::Arc;
 15use workspace::{AppState, JoinProject, ToggleFollow, Workspace};
 16
 17pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
 18    collab_titlebar_item::init(cx);
 19    contact_notification::init(cx);
 20    contact_list::init(cx);
 21    contact_finder::init(cx);
 22    contacts_popover::init(cx);
 23    incoming_call_notification::init(cx);
 24    project_shared_notification::init(cx);
 25
 26    cx.add_global_action(move |action: &JoinProject, cx| {
 27        let project_id = action.project_id;
 28        let follow_user_id = action.follow_user_id;
 29        let app_state = app_state.clone();
 30        cx.spawn(|mut cx| async move {
 31            let existing_workspace = cx.update(|cx| {
 32                cx.window_ids()
 33                    .filter_map(|window_id| cx.root_view::<Workspace>(window_id))
 34                    .find(|workspace| {
 35                        workspace.read(cx).project().read(cx).remote_id() == Some(project_id)
 36                    })
 37            });
 38
 39            let workspace = if let Some(existing_workspace) = existing_workspace {
 40                existing_workspace
 41            } else {
 42                let project = Project::remote(
 43                    project_id,
 44                    app_state.client.clone(),
 45                    app_state.user_store.clone(),
 46                    app_state.project_store.clone(),
 47                    app_state.languages.clone(),
 48                    app_state.fs.clone(),
 49                    cx.clone(),
 50                )
 51                .await?;
 52
 53                let (_, workspace) = cx.add_window((app_state.build_window_options)(), |cx| {
 54                    let mut workspace = Workspace::new(
 55                        Default::default(),
 56                        0,
 57                        project,
 58                        app_state.default_item_factory,
 59                        cx,
 60                    );
 61                    (app_state.initialize_workspace)(&mut workspace, &app_state, cx);
 62                    workspace
 63                });
 64                workspace
 65            };
 66
 67            cx.activate_window(workspace.window_id());
 68            cx.platform().activate(true);
 69
 70            workspace.update(&mut cx, |workspace, cx| {
 71                if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() {
 72                    let follow_peer_id = room
 73                        .read(cx)
 74                        .remote_participants()
 75                        .iter()
 76                        .find(|(_, participant)| participant.user.id == follow_user_id)
 77                        .map(|(peer_id, _)| *peer_id)
 78                        .or_else(|| {
 79                            // If we couldn't follow the given user, follow the host instead.
 80                            let collaborator = workspace
 81                                .project()
 82                                .read(cx)
 83                                .collaborators()
 84                                .values()
 85                                .find(|collaborator| collaborator.replica_id == 0)?;
 86                            Some(collaborator.peer_id)
 87                        });
 88
 89                    if let Some(follow_peer_id) = follow_peer_id {
 90                        if !workspace.is_following(follow_peer_id) {
 91                            workspace
 92                                .toggle_follow(&ToggleFollow(follow_peer_id), cx)
 93                                .map(|follow| follow.detach_and_log_err(cx));
 94                        }
 95                    }
 96                }
 97            });
 98
 99            anyhow::Ok(())
100        })
101        .detach_and_log_err(cx);
102    });
103}