mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 18:41:10 +00:00
Rename Collaborators to Contacts
This will allow us to use the word "collaborator" to describe users that are actively collaborating on a worktree. Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
9f29eeda03
commit
cd2c3c3606
6 changed files with 113 additions and 125 deletions
|
@ -20,7 +20,7 @@ pub struct User {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Collaborator {
|
pub struct Contact {
|
||||||
pub user: Arc<User>,
|
pub user: Arc<User>,
|
||||||
pub worktrees: Vec<WorktreeMetadata>,
|
pub worktrees: Vec<WorktreeMetadata>,
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,10 @@ pub struct WorktreeMetadata {
|
||||||
pub struct UserStore {
|
pub struct UserStore {
|
||||||
users: HashMap<u64, Arc<User>>,
|
users: HashMap<u64, Arc<User>>,
|
||||||
current_user: watch::Receiver<Option<Arc<User>>>,
|
current_user: watch::Receiver<Option<Arc<User>>>,
|
||||||
collaborators: Arc<[Collaborator]>,
|
contacts: Arc<[Contact]>,
|
||||||
rpc: Arc<Client>,
|
rpc: Arc<Client>,
|
||||||
http: Arc<dyn HttpClient>,
|
http: Arc<dyn HttpClient>,
|
||||||
_maintain_collaborators: Task<()>,
|
_maintain_contacts: Task<()>,
|
||||||
_maintain_current_user: Task<()>,
|
_maintain_current_user: Task<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,26 +52,26 @@ impl Entity for UserStore {
|
||||||
impl UserStore {
|
impl UserStore {
|
||||||
pub fn new(rpc: Arc<Client>, http: Arc<dyn HttpClient>, cx: &mut ModelContext<Self>) -> Self {
|
pub fn new(rpc: Arc<Client>, http: Arc<dyn HttpClient>, cx: &mut ModelContext<Self>) -> Self {
|
||||||
let (mut current_user_tx, current_user_rx) = watch::channel();
|
let (mut current_user_tx, current_user_rx) = watch::channel();
|
||||||
let (mut update_collaborators_tx, mut update_collaborators_rx) =
|
let (mut update_contacts_tx, mut update_contacts_rx) =
|
||||||
watch::channel::<Option<proto::UpdateCollaborators>>();
|
watch::channel::<Option<proto::UpdateContacts>>();
|
||||||
let update_collaborators_subscription = rpc.subscribe(
|
let update_contacts_subscription = rpc.subscribe(
|
||||||
cx,
|
cx,
|
||||||
move |_: &mut Self, msg: TypedEnvelope<proto::UpdateCollaborators>, _, _| {
|
move |_: &mut Self, msg: TypedEnvelope<proto::UpdateContacts>, _, _| {
|
||||||
let _ = update_collaborators_tx.blocking_send(Some(msg.payload));
|
let _ = update_contacts_tx.blocking_send(Some(msg.payload));
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Self {
|
Self {
|
||||||
users: Default::default(),
|
users: Default::default(),
|
||||||
current_user: current_user_rx,
|
current_user: current_user_rx,
|
||||||
collaborators: Arc::from([]),
|
contacts: Arc::from([]),
|
||||||
rpc: rpc.clone(),
|
rpc: rpc.clone(),
|
||||||
http,
|
http,
|
||||||
_maintain_collaborators: cx.spawn_weak(|this, mut cx| async move {
|
_maintain_contacts: cx.spawn_weak(|this, mut cx| async move {
|
||||||
let _subscription = update_collaborators_subscription;
|
let _subscription = update_contacts_subscription;
|
||||||
while let Some(message) = update_collaborators_rx.recv().await {
|
while let Some(message) = update_contacts_rx.recv().await {
|
||||||
if let Some((message, this)) = message.zip(this.upgrade(&cx)) {
|
if let Some((message, this)) = message.zip(this.upgrade(&cx)) {
|
||||||
this.update(&mut cx, |this, cx| this.update_collaborators(message, cx))
|
this.update(&mut cx, |this, cx| this.update_contacts(message, cx))
|
||||||
.log_err()
|
.log_err()
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
@ -100,35 +100,29 @@ impl UserStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_collaborators(
|
fn update_contacts(
|
||||||
&mut self,
|
&mut self,
|
||||||
message: proto::UpdateCollaborators,
|
message: proto::UpdateContacts,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
let mut user_ids = HashSet::new();
|
let mut user_ids = HashSet::new();
|
||||||
for collaborator in &message.collaborators {
|
for contact in &message.contacts {
|
||||||
user_ids.insert(collaborator.user_id);
|
user_ids.insert(contact.user_id);
|
||||||
user_ids.extend(
|
user_ids.extend(contact.worktrees.iter().flat_map(|w| &w.guests).copied());
|
||||||
collaborator
|
|
||||||
.worktrees
|
|
||||||
.iter()
|
|
||||||
.flat_map(|w| &w.guests)
|
|
||||||
.copied(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let load_users = self.load_users(user_ids.into_iter().collect(), cx);
|
let load_users = self.load_users(user_ids.into_iter().collect(), cx);
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
load_users.await?;
|
load_users.await?;
|
||||||
|
|
||||||
let mut collaborators = Vec::new();
|
let mut contacts = Vec::new();
|
||||||
for collaborator in message.collaborators {
|
for contact in message.contacts {
|
||||||
collaborators.push(Collaborator::from_proto(collaborator, &this, &mut cx).await?);
|
contacts.push(Contact::from_proto(contact, &this, &mut cx).await?);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
collaborators.sort_by(|a, b| a.user.github_login.cmp(&b.user.github_login));
|
contacts.sort_by(|a, b| a.user.github_login.cmp(&b.user.github_login));
|
||||||
this.collaborators = collaborators.into();
|
this.contacts = contacts.into();
|
||||||
cx.notify();
|
cx.notify();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -136,8 +130,8 @@ impl UserStore {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collaborators(&self) -> &Arc<[Collaborator]> {
|
pub fn contacts(&self) -> &Arc<[Contact]> {
|
||||||
&self.collaborators
|
&self.contacts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_users(
|
pub fn load_users(
|
||||||
|
@ -212,19 +206,19 @@ impl User {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collaborator {
|
impl Contact {
|
||||||
async fn from_proto(
|
async fn from_proto(
|
||||||
collaborator: proto::Collaborator,
|
contact: proto::Contact,
|
||||||
user_store: &ModelHandle<UserStore>,
|
user_store: &ModelHandle<UserStore>,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let user = user_store
|
let user = user_store
|
||||||
.update(cx, |user_store, cx| {
|
.update(cx, |user_store, cx| {
|
||||||
user_store.fetch_user(collaborator.user_id, cx)
|
user_store.fetch_user(contact.user_id, cx)
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let mut worktrees = Vec::new();
|
let mut worktrees = Vec::new();
|
||||||
for worktree in collaborator.worktrees {
|
for worktree in contact.worktrees {
|
||||||
let mut guests = Vec::new();
|
let mut guests = Vec::new();
|
||||||
for participant_id in worktree.guests {
|
for participant_id in worktree.guests {
|
||||||
guests.push(
|
guests.push(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use client::{Collaborator, UserStore};
|
use client::{Contact, UserStore};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action,
|
action,
|
||||||
elements::*,
|
elements::*,
|
||||||
|
@ -24,10 +24,10 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PeoplePanel {
|
pub struct PeoplePanel {
|
||||||
collaborators: ListState,
|
contacts: ListState,
|
||||||
user_store: ModelHandle<UserStore>,
|
user_store: ModelHandle<UserStore>,
|
||||||
settings: watch::Receiver<Settings>,
|
settings: watch::Receiver<Settings>,
|
||||||
_maintain_collaborators: Subscription,
|
_maintain_contacts: Subscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PeoplePanel {
|
impl PeoplePanel {
|
||||||
|
@ -37,8 +37,8 @@ impl PeoplePanel {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
collaborators: ListState::new(
|
contacts: ListState::new(
|
||||||
user_store.read(cx).collaborators().len(),
|
user_store.read(cx).contacts().len(),
|
||||||
Orientation::Top,
|
Orientation::Top,
|
||||||
1000.,
|
1000.,
|
||||||
{
|
{
|
||||||
|
@ -46,10 +46,10 @@ impl PeoplePanel {
|
||||||
let settings = settings.clone();
|
let settings = settings.clone();
|
||||||
move |ix, cx| {
|
move |ix, cx| {
|
||||||
let user_store = user_store.read(cx);
|
let user_store = user_store.read(cx);
|
||||||
let collaborators = user_store.collaborators().clone();
|
let contacts = user_store.contacts().clone();
|
||||||
let current_user_id = user_store.current_user().map(|user| user.id);
|
let current_user_id = user_store.current_user().map(|user| user.id);
|
||||||
Self::render_collaborator(
|
Self::render_collaborator(
|
||||||
&collaborators[ix],
|
&contacts[ix],
|
||||||
current_user_id,
|
current_user_id,
|
||||||
&settings.borrow().theme,
|
&settings.borrow().theme,
|
||||||
cx,
|
cx,
|
||||||
|
@ -57,7 +57,7 @@ impl PeoplePanel {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
_maintain_collaborators: cx.observe(&user_store, Self::update_collaborators),
|
_maintain_contacts: cx.observe(&user_store, Self::update_contacts),
|
||||||
user_store,
|
user_store,
|
||||||
settings,
|
settings,
|
||||||
}
|
}
|
||||||
|
@ -103,14 +103,14 @@ impl PeoplePanel {
|
||||||
.update(cx, |p, cx| p.close_remote_worktree(action.0, cx));
|
.update(cx, |p, cx| p.close_remote_worktree(action.0, cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_collaborators(&mut self, _: ModelHandle<UserStore>, cx: &mut ViewContext<Self>) {
|
fn update_contacts(&mut self, _: ModelHandle<UserStore>, cx: &mut ViewContext<Self>) {
|
||||||
self.collaborators
|
self.contacts
|
||||||
.reset(self.user_store.read(cx).collaborators().len());
|
.reset(self.user_store.read(cx).contacts().len());
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_collaborator(
|
fn render_collaborator(
|
||||||
collaborator: &Collaborator,
|
collaborator: &Contact,
|
||||||
current_user_id: Option<u64>,
|
current_user_id: Option<u64>,
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
cx: &mut LayoutContext,
|
cx: &mut LayoutContext,
|
||||||
|
@ -305,7 +305,7 @@ impl View for PeoplePanel {
|
||||||
|
|
||||||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||||
let theme = &self.settings.borrow().theme.people_panel;
|
let theme = &self.settings.borrow().theme.people_panel;
|
||||||
Container::new(List::new(self.collaborators.clone()).boxed())
|
Container::new(List::new(self.contacts.clone()).boxed())
|
||||||
.with_style(theme.container)
|
.with_style(theme.container)
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ message Envelope {
|
||||||
OpenWorktree open_worktree = 33;
|
OpenWorktree open_worktree = 33;
|
||||||
OpenWorktreeResponse open_worktree_response = 34;
|
OpenWorktreeResponse open_worktree_response = 34;
|
||||||
UnshareWorktree unshare_worktree = 35;
|
UnshareWorktree unshare_worktree = 35;
|
||||||
UpdateCollaborators update_collaborators = 36;
|
UpdateContacts update_contacts = 36;
|
||||||
LeaveWorktree leave_worktree = 37;
|
LeaveWorktree leave_worktree = 37;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,8 +190,8 @@ message GetChannelMessagesResponse {
|
||||||
bool done = 2;
|
bool done = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateCollaborators {
|
message UpdateContacts {
|
||||||
repeated Collaborator collaborators = 1;
|
repeated Contact contacts = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entities
|
// Entities
|
||||||
|
@ -358,7 +358,7 @@ message ChannelMessage {
|
||||||
Nonce nonce = 5;
|
Nonce nonce = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Collaborator {
|
message Contact {
|
||||||
uint64 user_id = 1;
|
uint64 user_id = 1;
|
||||||
repeated WorktreeMetadata worktrees = 2;
|
repeated WorktreeMetadata worktrees = 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ messages!(
|
||||||
GetChannelMessagesResponse,
|
GetChannelMessagesResponse,
|
||||||
GetChannels,
|
GetChannels,
|
||||||
GetChannelsResponse,
|
GetChannelsResponse,
|
||||||
UpdateCollaborators,
|
UpdateContacts,
|
||||||
GetUsers,
|
GetUsers,
|
||||||
GetUsersResponse,
|
GetUsersResponse,
|
||||||
JoinChannel,
|
JoinChannel,
|
||||||
|
|
|
@ -118,8 +118,8 @@ impl Server {
|
||||||
let (connection_id, handle_io, mut incoming_rx) =
|
let (connection_id, handle_io, mut incoming_rx) =
|
||||||
this.peer.add_connection(connection).await;
|
this.peer.add_connection(connection).await;
|
||||||
this.state_mut().add_connection(connection_id, user_id);
|
this.state_mut().add_connection(connection_id, user_id);
|
||||||
if let Err(err) = this.update_collaborators_for_users(&[user_id]).await {
|
if let Err(err) = this.update_contacts_for_users(&[user_id]).await {
|
||||||
log::error!("error updating collaborators for {:?}: {}", user_id, err);
|
log::error!("error updating contacts for {:?}: {}", user_id, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
let handle_io = handle_io.fuse();
|
let handle_io = handle_io.fuse();
|
||||||
|
@ -196,7 +196,7 @@ impl Server {
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_collaborators_for_users(removed_connection.collaborator_ids.iter())
|
self.update_contacts_for_users(removed_connection.contact_ids.iter())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -214,12 +214,12 @@ impl Server {
|
||||||
let receipt = request.receipt();
|
let receipt = request.receipt();
|
||||||
let host_user_id = self.state().user_id_for_connection(request.sender_id)?;
|
let host_user_id = self.state().user_id_for_connection(request.sender_id)?;
|
||||||
|
|
||||||
let mut collaborator_user_ids = HashSet::new();
|
let mut contact_user_ids = HashSet::new();
|
||||||
collaborator_user_ids.insert(host_user_id);
|
contact_user_ids.insert(host_user_id);
|
||||||
for github_login in request.payload.collaborator_logins {
|
for github_login in request.payload.collaborator_logins {
|
||||||
match self.app_state.db.create_user(&github_login, false).await {
|
match self.app_state.db.create_user(&github_login, false).await {
|
||||||
Ok(collaborator_user_id) => {
|
Ok(contact_user_id) => {
|
||||||
collaborator_user_ids.insert(collaborator_user_id);
|
contact_user_ids.insert(contact_user_id);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let message = err.to_string();
|
let message = err.to_string();
|
||||||
|
@ -231,11 +231,11 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let collaborator_user_ids = collaborator_user_ids.into_iter().collect::<Vec<_>>();
|
let contact_user_ids = contact_user_ids.into_iter().collect::<Vec<_>>();
|
||||||
let worktree_id = self.state_mut().add_worktree(Worktree {
|
let worktree_id = self.state_mut().add_worktree(Worktree {
|
||||||
host_connection_id: request.sender_id,
|
host_connection_id: request.sender_id,
|
||||||
host_user_id,
|
host_user_id,
|
||||||
collaborator_user_ids: collaborator_user_ids.clone(),
|
contact_user_ids: contact_user_ids.clone(),
|
||||||
root_name: request.payload.root_name,
|
root_name: request.payload.root_name,
|
||||||
share: None,
|
share: None,
|
||||||
});
|
});
|
||||||
|
@ -243,8 +243,7 @@ impl Server {
|
||||||
self.peer
|
self.peer
|
||||||
.respond(receipt, proto::OpenWorktreeResponse { worktree_id })
|
.respond(receipt, proto::OpenWorktreeResponse { worktree_id })
|
||||||
.await?;
|
.await?;
|
||||||
self.update_collaborators_for_users(&collaborator_user_ids)
|
self.update_contacts_for_users(&contact_user_ids).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -269,7 +268,7 @@ impl Server {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
self.update_collaborators_for_users(&worktree.collaborator_user_ids)
|
self.update_contacts_for_users(&worktree.contact_user_ids)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -288,15 +287,14 @@ impl Server {
|
||||||
.map(|entry| (entry.id, entry))
|
.map(|entry| (entry.id, entry))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let collaborator_user_ids =
|
let contact_user_ids =
|
||||||
self.state_mut()
|
self.state_mut()
|
||||||
.share_worktree(worktree.id, request.sender_id, entries);
|
.share_worktree(worktree.id, request.sender_id, entries);
|
||||||
if let Some(collaborator_user_ids) = collaborator_user_ids {
|
if let Some(contact_user_ids) = contact_user_ids {
|
||||||
self.peer
|
self.peer
|
||||||
.respond(request.receipt(), proto::ShareWorktreeResponse {})
|
.respond(request.receipt(), proto::ShareWorktreeResponse {})
|
||||||
.await?;
|
.await?;
|
||||||
self.update_collaborators_for_users(&collaborator_user_ids)
|
self.update_contacts_for_users(&contact_user_ids).await?;
|
||||||
.await?;
|
|
||||||
} else {
|
} else {
|
||||||
self.peer
|
self.peer
|
||||||
.respond_with_error(
|
.respond_with_error(
|
||||||
|
@ -324,7 +322,7 @@ impl Server {
|
||||||
.send(conn_id, proto::UnshareWorktree { worktree_id })
|
.send(conn_id, proto::UnshareWorktree { worktree_id })
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
self.update_collaborators_for_users(&worktree.collaborator_ids)
|
self.update_contacts_for_users(&worktree.contact_ids)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -368,12 +366,12 @@ impl Server {
|
||||||
peers,
|
peers,
|
||||||
};
|
};
|
||||||
let connection_ids = joined.worktree.connection_ids();
|
let connection_ids = joined.worktree.connection_ids();
|
||||||
let collaborator_user_ids = joined.worktree.collaborator_user_ids.clone();
|
let contact_user_ids = joined.worktree.contact_user_ids.clone();
|
||||||
Ok((response, connection_ids, collaborator_user_ids))
|
Ok((response, connection_ids, contact_user_ids))
|
||||||
});
|
});
|
||||||
|
|
||||||
match response_data {
|
match response_data {
|
||||||
Ok((response, connection_ids, collaborator_user_ids)) => {
|
Ok((response, connection_ids, contact_user_ids)) => {
|
||||||
broadcast(request.sender_id, connection_ids, |conn_id| {
|
broadcast(request.sender_id, connection_ids, |conn_id| {
|
||||||
self.peer.send(
|
self.peer.send(
|
||||||
conn_id,
|
conn_id,
|
||||||
|
@ -389,8 +387,7 @@ impl Server {
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
self.peer.respond(request.receipt(), response).await?;
|
self.peer.respond(request.receipt(), response).await?;
|
||||||
self.update_collaborators_for_users(&collaborator_user_ids)
|
self.update_contacts_for_users(&contact_user_ids).await?;
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
self.peer
|
self.peer
|
||||||
|
@ -425,7 +422,7 @@ impl Server {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
self.update_collaborators_for_users(&worktree.collaborator_ids)
|
self.update_contacts_for_users(&worktree.contact_ids)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -595,7 +592,7 @@ impl Server {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_collaborators_for_users<'a>(
|
async fn update_contacts_for_users<'a>(
|
||||||
self: &Arc<Server>,
|
self: &Arc<Server>,
|
||||||
user_ids: impl IntoIterator<Item = &'a UserId>,
|
user_ids: impl IntoIterator<Item = &'a UserId>,
|
||||||
) -> tide::Result<()> {
|
) -> tide::Result<()> {
|
||||||
|
@ -604,12 +601,12 @@ impl Server {
|
||||||
{
|
{
|
||||||
let state = self.state();
|
let state = self.state();
|
||||||
for user_id in user_ids {
|
for user_id in user_ids {
|
||||||
let collaborators = state.collaborators_for_user(*user_id);
|
let contacts = state.contacts_for_user(*user_id);
|
||||||
for connection_id in state.connection_ids_for_user(*user_id) {
|
for connection_id in state.connection_ids_for_user(*user_id) {
|
||||||
send_futures.push(self.peer.send(
|
send_futures.push(self.peer.send(
|
||||||
connection_id,
|
connection_id,
|
||||||
proto::UpdateCollaborators {
|
proto::UpdateContacts {
|
||||||
collaborators: collaborators.clone(),
|
contacts: contacts.clone(),
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2108,7 +2105,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_collaborators(
|
async fn test_contacts(
|
||||||
mut cx_a: TestAppContext,
|
mut cx_a: TestAppContext,
|
||||||
mut cx_b: TestAppContext,
|
mut cx_b: TestAppContext,
|
||||||
mut cx_c: TestAppContext,
|
mut cx_c: TestAppContext,
|
||||||
|
@ -2145,17 +2142,17 @@ mod tests {
|
||||||
|
|
||||||
user_store_a
|
user_store_a
|
||||||
.condition(&cx_a, |user_store, _| {
|
.condition(&cx_a, |user_store, _| {
|
||||||
collaborators(user_store) == vec![("user_a", vec![("a", vec![])])]
|
contacts(user_store) == vec![("user_a", vec![("a", vec![])])]
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
user_store_b
|
user_store_b
|
||||||
.condition(&cx_b, |user_store, _| {
|
.condition(&cx_b, |user_store, _| {
|
||||||
collaborators(user_store) == vec![("user_a", vec![("a", vec![])])]
|
contacts(user_store) == vec![("user_a", vec![("a", vec![])])]
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
user_store_c
|
user_store_c
|
||||||
.condition(&cx_c, |user_store, _| {
|
.condition(&cx_c, |user_store, _| {
|
||||||
collaborators(user_store) == vec![("user_a", vec![("a", vec![])])]
|
contacts(user_store) == vec![("user_a", vec![("a", vec![])])]
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -2175,37 +2172,37 @@ mod tests {
|
||||||
|
|
||||||
user_store_a
|
user_store_a
|
||||||
.condition(&cx_a, |user_store, _| {
|
.condition(&cx_a, |user_store, _| {
|
||||||
collaborators(user_store) == vec![("user_a", vec![("a", vec!["user_b"])])]
|
contacts(user_store) == vec![("user_a", vec![("a", vec!["user_b"])])]
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
user_store_b
|
user_store_b
|
||||||
.condition(&cx_b, |user_store, _| {
|
.condition(&cx_b, |user_store, _| {
|
||||||
collaborators(user_store) == vec![("user_a", vec![("a", vec!["user_b"])])]
|
contacts(user_store) == vec![("user_a", vec![("a", vec!["user_b"])])]
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
user_store_c
|
user_store_c
|
||||||
.condition(&cx_c, |user_store, _| {
|
.condition(&cx_c, |user_store, _| {
|
||||||
collaborators(user_store) == vec![("user_a", vec![("a", vec!["user_b"])])]
|
contacts(user_store) == vec![("user_a", vec![("a", vec!["user_b"])])]
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
cx_a.update(move |_| drop(worktree_a));
|
cx_a.update(move |_| drop(worktree_a));
|
||||||
user_store_a
|
user_store_a
|
||||||
.condition(&cx_a, |user_store, _| collaborators(user_store) == vec![])
|
.condition(&cx_a, |user_store, _| contacts(user_store) == vec![])
|
||||||
.await;
|
.await;
|
||||||
user_store_b
|
user_store_b
|
||||||
.condition(&cx_b, |user_store, _| collaborators(user_store) == vec![])
|
.condition(&cx_b, |user_store, _| contacts(user_store) == vec![])
|
||||||
.await;
|
.await;
|
||||||
user_store_c
|
user_store_c
|
||||||
.condition(&cx_c, |user_store, _| collaborators(user_store) == vec![])
|
.condition(&cx_c, |user_store, _| contacts(user_store) == vec![])
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
fn collaborators(user_store: &UserStore) -> Vec<(&str, Vec<(&str, Vec<&str>)>)> {
|
fn contacts(user_store: &UserStore) -> Vec<(&str, Vec<(&str, Vec<&str>)>)> {
|
||||||
user_store
|
user_store
|
||||||
.collaborators()
|
.contacts()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|collaborator| {
|
.map(|contact| {
|
||||||
let worktrees = collaborator
|
let worktrees = contact
|
||||||
.worktrees
|
.worktrees
|
||||||
.iter()
|
.iter()
|
||||||
.map(|w| {
|
.map(|w| {
|
||||||
|
@ -2215,7 +2212,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
(collaborator.user.github_login.as_str(), worktrees)
|
(contact.user.github_login.as_str(), worktrees)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct ConnectionState {
|
||||||
pub struct Worktree {
|
pub struct Worktree {
|
||||||
pub host_connection_id: ConnectionId,
|
pub host_connection_id: ConnectionId,
|
||||||
pub host_user_id: UserId,
|
pub host_user_id: UserId,
|
||||||
pub collaborator_user_ids: Vec<UserId>,
|
pub contact_user_ids: Vec<UserId>,
|
||||||
pub root_name: String,
|
pub root_name: String,
|
||||||
pub share: Option<WorktreeShare>,
|
pub share: Option<WorktreeShare>,
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ pub type ReplicaId = u16;
|
||||||
pub struct RemovedConnectionState {
|
pub struct RemovedConnectionState {
|
||||||
pub hosted_worktrees: HashMap<u64, Worktree>,
|
pub hosted_worktrees: HashMap<u64, Worktree>,
|
||||||
pub guest_worktree_ids: HashMap<u64, Vec<ConnectionId>>,
|
pub guest_worktree_ids: HashMap<u64, Vec<ConnectionId>>,
|
||||||
pub collaborator_ids: HashSet<UserId>,
|
pub contact_ids: HashSet<UserId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct JoinedWorktree<'a> {
|
pub struct JoinedWorktree<'a> {
|
||||||
|
@ -54,12 +54,12 @@ pub struct JoinedWorktree<'a> {
|
||||||
|
|
||||||
pub struct UnsharedWorktree {
|
pub struct UnsharedWorktree {
|
||||||
pub connection_ids: Vec<ConnectionId>,
|
pub connection_ids: Vec<ConnectionId>,
|
||||||
pub collaborator_ids: Vec<UserId>,
|
pub contact_ids: Vec<UserId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LeftWorktree {
|
pub struct LeftWorktree {
|
||||||
pub connection_ids: Vec<ConnectionId>,
|
pub connection_ids: Vec<ConnectionId>,
|
||||||
pub collaborator_ids: Vec<UserId>,
|
pub contact_ids: Vec<UserId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
|
@ -107,14 +107,14 @@ impl Store {
|
||||||
for worktree_id in connection.worktrees.clone() {
|
for worktree_id in connection.worktrees.clone() {
|
||||||
if let Ok(worktree) = self.remove_worktree(worktree_id, connection_id) {
|
if let Ok(worktree) = self.remove_worktree(worktree_id, connection_id) {
|
||||||
result
|
result
|
||||||
.collaborator_ids
|
.contact_ids
|
||||||
.extend(worktree.collaborator_user_ids.iter().copied());
|
.extend(worktree.contact_user_ids.iter().copied());
|
||||||
result.hosted_worktrees.insert(worktree_id, worktree);
|
result.hosted_worktrees.insert(worktree_id, worktree);
|
||||||
} else if let Some(worktree) = self.leave_worktree(connection_id, worktree_id) {
|
} else if let Some(worktree) = self.leave_worktree(connection_id, worktree_id) {
|
||||||
result
|
result
|
||||||
.guest_worktree_ids
|
.guest_worktree_ids
|
||||||
.insert(worktree_id, worktree.connection_ids);
|
.insert(worktree_id, worktree.connection_ids);
|
||||||
result.collaborator_ids.extend(worktree.collaborator_ids);
|
result.contact_ids.extend(worktree.contact_ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,8 +171,8 @@ impl Store {
|
||||||
.copied()
|
.copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collaborators_for_user(&self, user_id: UserId) -> Vec<proto::Collaborator> {
|
pub fn contacts_for_user(&self, user_id: UserId) -> Vec<proto::Contact> {
|
||||||
let mut collaborators = HashMap::new();
|
let mut contacts = HashMap::new();
|
||||||
for worktree_id in self
|
for worktree_id in self
|
||||||
.visible_worktrees_by_user_id
|
.visible_worktrees_by_user_id
|
||||||
.get(&user_id)
|
.get(&user_id)
|
||||||
|
@ -190,9 +190,9 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(host_user_id) = self.user_id_for_connection(worktree.host_connection_id) {
|
if let Ok(host_user_id) = self.user_id_for_connection(worktree.host_connection_id) {
|
||||||
collaborators
|
contacts
|
||||||
.entry(host_user_id)
|
.entry(host_user_id)
|
||||||
.or_insert_with(|| proto::Collaborator {
|
.or_insert_with(|| proto::Contact {
|
||||||
user_id: host_user_id.to_proto(),
|
user_id: host_user_id.to_proto(),
|
||||||
worktrees: Vec::new(),
|
worktrees: Vec::new(),
|
||||||
})
|
})
|
||||||
|
@ -206,14 +206,14 @@ impl Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collaborators.into_values().collect()
|
contacts.into_values().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_worktree(&mut self, worktree: Worktree) -> u64 {
|
pub fn add_worktree(&mut self, worktree: Worktree) -> u64 {
|
||||||
let worktree_id = self.next_worktree_id;
|
let worktree_id = self.next_worktree_id;
|
||||||
for collaborator_user_id in &worktree.collaborator_user_ids {
|
for contact_user_id in &worktree.contact_user_ids {
|
||||||
self.visible_worktrees_by_user_id
|
self.visible_worktrees_by_user_id
|
||||||
.entry(*collaborator_user_id)
|
.entry(*contact_user_id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(worktree_id);
|
.insert(worktree_id);
|
||||||
}
|
}
|
||||||
|
@ -255,10 +255,9 @@ impl Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for collaborator_user_id in &worktree.collaborator_user_ids {
|
for contact_user_id in &worktree.contact_user_ids {
|
||||||
if let Some(visible_worktrees) = self
|
if let Some(visible_worktrees) =
|
||||||
.visible_worktrees_by_user_id
|
self.visible_worktrees_by_user_id.get_mut(&contact_user_id)
|
||||||
.get_mut(&collaborator_user_id)
|
|
||||||
{
|
{
|
||||||
visible_worktrees.remove(&worktree_id);
|
visible_worktrees.remove(&worktree_id);
|
||||||
}
|
}
|
||||||
|
@ -283,7 +282,7 @@ impl Store {
|
||||||
active_replica_ids: Default::default(),
|
active_replica_ids: Default::default(),
|
||||||
entries,
|
entries,
|
||||||
});
|
});
|
||||||
return Some(worktree.collaborator_user_ids.clone());
|
return Some(worktree.contact_user_ids.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -305,7 +304,7 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
let connection_ids = worktree.connection_ids();
|
let connection_ids = worktree.connection_ids();
|
||||||
let collaborator_ids = worktree.collaborator_user_ids.clone();
|
let contact_ids = worktree.contact_user_ids.clone();
|
||||||
if let Some(share) = worktree.share.take() {
|
if let Some(share) = worktree.share.take() {
|
||||||
for connection_id in share.guests.into_keys() {
|
for connection_id in share.guests.into_keys() {
|
||||||
if let Some(connection) = self.connections.get_mut(&connection_id) {
|
if let Some(connection) = self.connections.get_mut(&connection_id) {
|
||||||
|
@ -318,7 +317,7 @@ impl Store {
|
||||||
|
|
||||||
Ok(UnsharedWorktree {
|
Ok(UnsharedWorktree {
|
||||||
connection_ids,
|
connection_ids,
|
||||||
collaborator_ids,
|
contact_ids,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("worktree is not shared"))?
|
Err(anyhow!("worktree is not shared"))?
|
||||||
|
@ -339,7 +338,7 @@ impl Store {
|
||||||
.worktrees
|
.worktrees
|
||||||
.get_mut(&worktree_id)
|
.get_mut(&worktree_id)
|
||||||
.and_then(|worktree| {
|
.and_then(|worktree| {
|
||||||
if worktree.collaborator_user_ids.contains(&user_id) {
|
if worktree.contact_user_ids.contains(&user_id) {
|
||||||
Some(worktree)
|
Some(worktree)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -381,14 +380,14 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
let connection_ids = worktree.connection_ids();
|
let connection_ids = worktree.connection_ids();
|
||||||
let collaborator_ids = worktree.collaborator_user_ids.clone();
|
let contact_ids = worktree.contact_user_ids.clone();
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
self.check_invariants();
|
self.check_invariants();
|
||||||
|
|
||||||
Some(LeftWorktree {
|
Some(LeftWorktree {
|
||||||
connection_ids,
|
connection_ids,
|
||||||
collaborator_ids,
|
contact_ids,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,11 +529,9 @@ impl Store {
|
||||||
let host_connection = self.connections.get(&worktree.host_connection_id).unwrap();
|
let host_connection = self.connections.get(&worktree.host_connection_id).unwrap();
|
||||||
assert!(host_connection.worktrees.contains(worktree_id));
|
assert!(host_connection.worktrees.contains(worktree_id));
|
||||||
|
|
||||||
for collaborator_id in &worktree.collaborator_user_ids {
|
for contact_id in &worktree.contact_user_ids {
|
||||||
let visible_worktree_ids = self
|
let visible_worktree_ids =
|
||||||
.visible_worktrees_by_user_id
|
self.visible_worktrees_by_user_id.get(contact_id).unwrap();
|
||||||
.get(collaborator_id)
|
|
||||||
.unwrap();
|
|
||||||
assert!(visible_worktree_ids.contains(worktree_id));
|
assert!(visible_worktree_ids.contains(worktree_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,7 +555,7 @@ impl Store {
|
||||||
for (user_id, visible_worktree_ids) in &self.visible_worktrees_by_user_id {
|
for (user_id, visible_worktree_ids) in &self.visible_worktrees_by_user_id {
|
||||||
for worktree_id in visible_worktree_ids {
|
for worktree_id in visible_worktree_ids {
|
||||||
let worktree = self.worktrees.get(worktree_id).unwrap();
|
let worktree = self.worktrees.get(worktree_id).unwrap();
|
||||||
assert!(worktree.collaborator_user_ids.contains(user_id));
|
assert!(worktree.contact_user_ids.contains(user_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue