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:
Nathan Sobo 2021-11-26 10:59:41 -07:00
parent 9f29eeda03
commit cd2c3c3606
6 changed files with 113 additions and 125 deletions

View file

@ -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(

View file

@ -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()
} }

View file

@ -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;
} }

View file

@ -131,7 +131,7 @@ messages!(
GetChannelMessagesResponse, GetChannelMessagesResponse,
GetChannels, GetChannels,
GetChannelsResponse, GetChannelsResponse,
UpdateCollaborators, UpdateContacts,
GetUsers, GetUsers,
GetUsersResponse, GetUsersResponse,
JoinChannel, JoinChannel,

View file

@ -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()
} }

View file

@ -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));
} }
} }