diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 40ce95bce6..b8e16a8650 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -605,6 +605,7 @@ impl Server { guest_user_id = state.user_id_for_connection(request.sender_id)?; }; + tracing::info!(project_id, %host_user_id, %host_connection_id, "join project"); let has_contact = self .app_state .db @@ -760,6 +761,12 @@ impl Server { { let mut store = self.store_mut().await; project = store.leave_project(sender_id, project_id)?; + tracing::info!( + project_id, + host_user_id = %project.host_user_id, + host_connection_id = %project.host_connection_id, + "leave project" + ); if project.remove_collaborator { broadcast(sender_id, project.connection_ids, |conn_id| { @@ -833,6 +840,7 @@ impl Server { &request.payload.updated_entries, request.payload.scan_id, )?; + // TODO: log `extension_counts` from `Worktree`. broadcast(request.sender_id, connection_ids, |connection_id| { self.peer diff --git a/crates/collab/src/rpc/store.rs b/crates/collab/src/rpc/store.rs index cad293876e..1d88264d72 100644 --- a/crates/collab/src/rpc/store.rs +++ b/crates/collab/src/rpc/store.rs @@ -3,7 +3,13 @@ use anyhow::{anyhow, Result}; use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet}; use rpc::{proto, ConnectionId, Receipt}; use serde::Serialize; -use std::{collections::hash_map, mem, path::PathBuf}; +use std::{ + collections::hash_map, + ffi::{OsStr, OsString}, + mem, + path::{Path, PathBuf}, + str, +}; use tracing::instrument; #[derive(Default, Serialize)] @@ -43,6 +49,8 @@ pub struct Worktree { #[serde(skip)] pub entries: HashMap, #[serde(skip)] + pub extension_counts: HashMap, + #[serde(skip)] pub diagnostic_summaries: BTreeMap, pub scan_id: u64, } @@ -575,9 +583,22 @@ impl Store { let metadata_changed = worktree_root_name != worktree.root_name; worktree.root_name = worktree_root_name.to_string(); for entry_id in removed_entries { - worktree.entries.remove(&entry_id); + if let Some(entry) = worktree.entries.remove(&entry_id) { + if let Some(extension) = extension_for_entry(&entry) { + if let Some(count) = worktree.extension_counts.get_mut(extension) { + *count = count.saturating_sub(1); + } + } + } } for entry in updated_entries { + if let Some(extension) = extension_for_entry(&entry) { + if let Some(count) = worktree.extension_counts.get_mut(extension) { + *count += 1; + } else { + worktree.extension_counts.insert(extension.into(), 1); + } + } worktree.entries.insert(entry.id, entry.clone()); } worktree.scan_id = scan_id; @@ -732,3 +753,10 @@ impl Channel { self.connection_ids.iter().copied().collect() } } + +fn extension_for_entry(entry: &proto::Entry) -> Option<&OsStr> { + str::from_utf8(&entry.path) + .ok() + .map(Path::new) + .and_then(|p| p.extension()) +}