mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
parent
f67abd2943
commit
866d791760
@ -3,9 +3,7 @@ mod channel_index;
|
||||
use crate::{channel_buffer::ChannelBuffer, channel_chat::ChannelChat, ChannelMessage};
|
||||
use anyhow::{anyhow, Result};
|
||||
use channel_index::ChannelIndex;
|
||||
use client::{
|
||||
ChannelId, Client, ClientSettings, HostedProjectId, Subscription, User, UserId, UserStore,
|
||||
};
|
||||
use client::{ChannelId, Client, ClientSettings, ProjectId, Subscription, User, UserId, UserStore};
|
||||
use collections::{hash_map, HashMap, HashSet};
|
||||
use futures::{channel::mpsc, future::Shared, Future, FutureExt, StreamExt};
|
||||
use gpui::{
|
||||
@ -37,7 +35,7 @@ struct NotesVersion {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HostedProject {
|
||||
id: HostedProjectId,
|
||||
project_id: ProjectId,
|
||||
channel_id: ChannelId,
|
||||
name: SharedString,
|
||||
_visibility: proto::ChannelVisibility,
|
||||
@ -46,7 +44,7 @@ pub struct HostedProject {
|
||||
impl From<proto::HostedProject> for HostedProject {
|
||||
fn from(project: proto::HostedProject) -> Self {
|
||||
Self {
|
||||
id: HostedProjectId(project.id),
|
||||
project_id: ProjectId(project.project_id),
|
||||
channel_id: ChannelId(project.channel_id),
|
||||
_visibility: project.visibility(),
|
||||
name: project.name.into(),
|
||||
@ -59,7 +57,7 @@ pub struct ChannelStore {
|
||||
channel_invitations: Vec<Arc<Channel>>,
|
||||
channel_participants: HashMap<ChannelId, Vec<Arc<User>>>,
|
||||
channel_states: HashMap<ChannelId, ChannelState>,
|
||||
hosted_projects: HashMap<HostedProjectId, HostedProject>,
|
||||
hosted_projects: HashMap<ProjectId, HostedProject>,
|
||||
|
||||
outgoing_invites: HashSet<(ChannelId, UserId)>,
|
||||
update_channels_tx: mpsc::UnboundedSender<proto::UpdateChannels>,
|
||||
@ -88,7 +86,7 @@ pub struct ChannelState {
|
||||
observed_notes_version: NotesVersion,
|
||||
observed_chat_message: Option<u64>,
|
||||
role: Option<ChannelRole>,
|
||||
projects: HashSet<HostedProjectId>,
|
||||
projects: HashSet<ProjectId>,
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
@ -305,8 +303,8 @@ impl ChannelStore {
|
||||
self.channel_index.by_id().get(&channel_id)
|
||||
}
|
||||
|
||||
pub fn projects_for_id(&self, channel_id: ChannelId) -> Vec<(SharedString, HostedProjectId)> {
|
||||
let mut projects: Vec<(SharedString, HostedProjectId)> = self
|
||||
pub fn projects_for_id(&self, channel_id: ChannelId) -> Vec<(SharedString, ProjectId)> {
|
||||
let mut projects: Vec<(SharedString, ProjectId)> = self
|
||||
.channel_states
|
||||
.get(&channel_id)
|
||||
.map(|state| state.projects.clone())
|
||||
@ -1159,27 +1157,27 @@ impl ChannelStore {
|
||||
let hosted_project: HostedProject = hosted_project.into();
|
||||
if let Some(old_project) = self
|
||||
.hosted_projects
|
||||
.insert(hosted_project.id, hosted_project.clone())
|
||||
.insert(hosted_project.project_id, hosted_project.clone())
|
||||
{
|
||||
self.channel_states
|
||||
.entry(old_project.channel_id)
|
||||
.or_default()
|
||||
.remove_hosted_project(old_project.id);
|
||||
.remove_hosted_project(old_project.project_id);
|
||||
}
|
||||
self.channel_states
|
||||
.entry(hosted_project.channel_id)
|
||||
.or_default()
|
||||
.add_hosted_project(hosted_project.id);
|
||||
.add_hosted_project(hosted_project.project_id);
|
||||
}
|
||||
|
||||
for hosted_project_id in payload.deleted_hosted_projects {
|
||||
let hosted_project_id = HostedProjectId(hosted_project_id);
|
||||
let hosted_project_id = ProjectId(hosted_project_id);
|
||||
|
||||
if let Some(old_project) = self.hosted_projects.remove(&hosted_project_id) {
|
||||
self.channel_states
|
||||
.entry(old_project.channel_id)
|
||||
.or_default()
|
||||
.remove_hosted_project(old_project.id);
|
||||
.remove_hosted_project(old_project.project_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1289,11 +1287,11 @@ impl ChannelState {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_hosted_project(&mut self, project_id: HostedProjectId) {
|
||||
fn add_hosted_project(&mut self, project_id: ProjectId) {
|
||||
self.projects.insert(project_id);
|
||||
}
|
||||
|
||||
fn remove_hosted_project(&mut self, project_id: HostedProjectId) {
|
||||
fn remove_hosted_project(&mut self, project_id: ProjectId) {
|
||||
self.projects.remove(&project_id);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ impl std::fmt::Display for ChannelId {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
pub struct HostedProjectId(pub u64);
|
||||
pub struct ProjectId(pub u64);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct ParticipantIndex(pub u32);
|
||||
|
@ -9,20 +9,21 @@ impl Database {
|
||||
roles: &HashMap<ChannelId, ChannelRole>,
|
||||
tx: &DatabaseTransaction,
|
||||
) -> Result<Vec<proto::HostedProject>> {
|
||||
Ok(hosted_project::Entity::find()
|
||||
let projects = hosted_project::Entity::find()
|
||||
.find_also_related(project::Entity)
|
||||
.filter(hosted_project::Column::ChannelId.is_in(channel_ids.iter().map(|id| id.0)))
|
||||
.all(tx)
|
||||
.await?
|
||||
.into_iter()
|
||||
.flat_map(|project| {
|
||||
if project.deleted_at.is_some() {
|
||||
.flat_map(|(hosted_project, project)| {
|
||||
if hosted_project.deleted_at.is_some() {
|
||||
return None;
|
||||
}
|
||||
match project.visibility {
|
||||
match hosted_project.visibility {
|
||||
ChannelVisibility::Public => {}
|
||||
ChannelVisibility::Members => {
|
||||
let is_visible = roles
|
||||
.get(&project.channel_id)
|
||||
.get(&hosted_project.channel_id)
|
||||
.map(|role| role.can_see_all_descendants())
|
||||
.unwrap_or(false);
|
||||
if !is_visible {
|
||||
@ -31,13 +32,15 @@ impl Database {
|
||||
}
|
||||
};
|
||||
Some(proto::HostedProject {
|
||||
id: project.id.to_proto(),
|
||||
channel_id: project.channel_id.to_proto(),
|
||||
name: project.name.clone(),
|
||||
visibility: project.visibility.into(),
|
||||
project_id: project?.id.to_proto(),
|
||||
channel_id: hosted_project.channel_id.to_proto(),
|
||||
name: hosted_project.name.clone(),
|
||||
visibility: hosted_project.visibility.into(),
|
||||
})
|
||||
})
|
||||
.collect())
|
||||
.collect();
|
||||
|
||||
Ok(projects)
|
||||
}
|
||||
|
||||
pub async fn get_hosted_project(
|
||||
|
@ -512,18 +512,30 @@ impl Database {
|
||||
/// Adds the given connection to the specified hosted project
|
||||
pub async fn join_hosted_project(
|
||||
&self,
|
||||
id: HostedProjectId,
|
||||
id: ProjectId,
|
||||
user_id: UserId,
|
||||
connection: ConnectionId,
|
||||
) -> Result<(Project, ReplicaId)> {
|
||||
self.transaction(|tx| async move {
|
||||
let (hosted_project, role) = self.get_hosted_project(id, user_id, &tx).await?;
|
||||
let project = project::Entity::find()
|
||||
.filter(project::Column::HostedProjectId.eq(hosted_project.id))
|
||||
let (project, hosted_project) = project::Entity::find_by_id(id)
|
||||
.find_also_related(hosted_project::Entity)
|
||||
.one(&*tx)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow!("hosted project is no longer shared"))?;
|
||||
|
||||
let Some(hosted_project) = hosted_project else {
|
||||
return Err(anyhow!("project is not hosted"))?;
|
||||
};
|
||||
|
||||
let channel = channel::Entity::find_by_id(hosted_project.channel_id)
|
||||
.one(&*tx)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow!("no such channel"))?;
|
||||
|
||||
let role = self
|
||||
.check_user_is_channel_participant(&channel, user_id, &tx)
|
||||
.await?;
|
||||
|
||||
self.join_project_internal(project, user_id, connection, role, &tx)
|
||||
.await
|
||||
})
|
||||
|
@ -15,4 +15,13 @@ pub struct Model {
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
pub enum Relation {
|
||||
#[sea_orm(has_one = "super::project::Entity")]
|
||||
Project,
|
||||
}
|
||||
|
||||
impl Related<super::project::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Project.def()
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,12 @@ pub enum Relation {
|
||||
Collaborators,
|
||||
#[sea_orm(has_many = "super::language_server::Entity")]
|
||||
LanguageServers,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::hosted_project::Entity",
|
||||
from = "Column::HostedProjectId",
|
||||
to = "super::hosted_project::Column::Id"
|
||||
)]
|
||||
HostedProject,
|
||||
}
|
||||
|
||||
impl Related<super::user::Entity> for Entity {
|
||||
@ -82,4 +88,10 @@ impl Related<super::language_server::Entity> for Entity {
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::hosted_project::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::HostedProject.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
@ -4,9 +4,9 @@ use crate::{
|
||||
auth::{self, Impersonator},
|
||||
db::{
|
||||
self, BufferId, ChannelId, ChannelRole, ChannelsForUser, CreatedChannelMessage, Database,
|
||||
HostedProjectId, InviteMemberResult, MembershipUpdated, MessageId, NotificationId, Project,
|
||||
ProjectId, RemoveChannelMemberResult, ReplicaId, RespondToChannelInvite, RoomId, ServerId,
|
||||
User, UserId,
|
||||
InviteMemberResult, MembershipUpdated, MessageId, NotificationId, Project, ProjectId,
|
||||
RemoveChannelMemberResult, ReplicaId, RespondToChannelInvite, RoomId, ServerId, User,
|
||||
UserId,
|
||||
},
|
||||
executor::Executor,
|
||||
AppState, Error, Result,
|
||||
@ -1770,7 +1770,7 @@ async fn join_hosted_project(
|
||||
.db()
|
||||
.await
|
||||
.join_hosted_project(
|
||||
HostedProjectId(request.id as i32),
|
||||
ProjectId(request.project_id as i32),
|
||||
session.user_id,
|
||||
session.connection_id,
|
||||
)
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
};
|
||||
use call::ActiveCall;
|
||||
use channel::{Channel, ChannelEvent, ChannelStore};
|
||||
use client::{ChannelId, Client, Contact, HostedProjectId, User, UserStore};
|
||||
use client::{ChannelId, Client, Contact, ProjectId, User, UserStore};
|
||||
use contact_finder::ContactFinder;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
@ -185,7 +185,7 @@ enum ListEntry {
|
||||
depth: usize,
|
||||
},
|
||||
HostedProject {
|
||||
id: HostedProjectId,
|
||||
id: ProjectId,
|
||||
name: SharedString,
|
||||
},
|
||||
Contact {
|
||||
@ -1035,7 +1035,7 @@ impl CollabPanel {
|
||||
|
||||
fn render_channel_project(
|
||||
&self,
|
||||
id: HostedProjectId,
|
||||
id: ProjectId,
|
||||
name: &SharedString,
|
||||
is_selected: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
|
@ -12,8 +12,7 @@ mod project_tests;
|
||||
use anyhow::{anyhow, bail, Context as _, Result};
|
||||
use async_trait::async_trait;
|
||||
use client::{
|
||||
proto, Client, Collaborator, HostedProjectId, PendingEntitySubscription, TypedEnvelope,
|
||||
UserStore,
|
||||
proto, Client, Collaborator, PendingEntitySubscription, ProjectId, TypedEnvelope, UserStore,
|
||||
};
|
||||
use clock::ReplicaId;
|
||||
use collections::{hash_map, BTreeMap, HashMap, HashSet, VecDeque};
|
||||
@ -175,7 +174,7 @@ pub struct Project {
|
||||
prettiers_per_worktree: HashMap<WorktreeId, HashSet<Option<PathBuf>>>,
|
||||
prettier_instances: HashMap<PathBuf, PrettierInstance>,
|
||||
tasks: Model<Inventory>,
|
||||
hosted_project_id: Option<HostedProjectId>,
|
||||
hosted_project_id: Option<ProjectId>,
|
||||
}
|
||||
|
||||
pub enum LanguageServerToQuery {
|
||||
@ -780,29 +779,31 @@ impl Project {
|
||||
}
|
||||
|
||||
pub async fn hosted(
|
||||
_hosted_project_id: HostedProjectId,
|
||||
_user_store: Model<UserStore>,
|
||||
_client: Arc<Client>,
|
||||
_languages: Arc<LanguageRegistry>,
|
||||
_fs: Arc<dyn Fs>,
|
||||
_cx: AsyncAppContext,
|
||||
remote_id: ProjectId,
|
||||
user_store: Model<UserStore>,
|
||||
client: Arc<Client>,
|
||||
languages: Arc<LanguageRegistry>,
|
||||
fs: Arc<dyn Fs>,
|
||||
cx: AsyncAppContext,
|
||||
) -> Result<Model<Self>> {
|
||||
// let response = client
|
||||
// .request_envelope(proto::JoinHostedProject {
|
||||
// id: hosted_project_id.0,
|
||||
// })
|
||||
// .await?;
|
||||
// Self::from_join_project_response(
|
||||
// response,
|
||||
// Some(hosted_project_id),
|
||||
// client,
|
||||
// user_store,
|
||||
// languages,
|
||||
// fs,
|
||||
// cx,
|
||||
// )
|
||||
// .await
|
||||
Err(anyhow!("disabled"))
|
||||
client.authenticate_and_connect(true, &cx).await?;
|
||||
|
||||
let subscription = client.subscribe_to_entity(remote_id.0)?;
|
||||
let response = client
|
||||
.request_envelope(proto::JoinHostedProject {
|
||||
project_id: remote_id.0,
|
||||
})
|
||||
.await?;
|
||||
Self::from_join_project_response(
|
||||
response,
|
||||
subscription,
|
||||
client,
|
||||
user_store,
|
||||
languages,
|
||||
fs,
|
||||
cx,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
fn release(&mut self, cx: &mut AppContext) {
|
||||
@ -1050,7 +1051,7 @@ impl Project {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hosted_project_id(&self) -> Option<HostedProjectId> {
|
||||
pub fn hosted_project_id(&self) -> Option<ProjectId> {
|
||||
self.hosted_project_id
|
||||
}
|
||||
|
||||
|
@ -408,7 +408,7 @@ message JoinProject {
|
||||
}
|
||||
|
||||
message JoinHostedProject {
|
||||
uint64 id = 1;
|
||||
uint64 project_id = 1;
|
||||
}
|
||||
|
||||
message JoinProjectResponse {
|
||||
@ -1067,7 +1067,7 @@ message ChannelParticipants {
|
||||
}
|
||||
|
||||
message HostedProject {
|
||||
uint64 id = 1;
|
||||
uint64 project_id = 1;
|
||||
uint64 channel_id = 2;
|
||||
string name = 3;
|
||||
ChannelVisibility visibility = 4;
|
||||
|
@ -15,7 +15,7 @@ use anyhow::{anyhow, Context as _, Result};
|
||||
use call::{call_settings::CallSettings, ActiveCall};
|
||||
use client::{
|
||||
proto::{self, ErrorCode, PeerId},
|
||||
ChannelId, Client, ErrorExt, HostedProjectId, Status, TypedEnvelope, UserStore,
|
||||
ChannelId, Client, ErrorExt, ProjectId, Status, TypedEnvelope, UserStore,
|
||||
};
|
||||
use collections::{hash_map, HashMap, HashSet};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
@ -4462,7 +4462,7 @@ pub fn create_and_open_local_file(
|
||||
}
|
||||
|
||||
pub fn join_hosted_project(
|
||||
hosted_project_id: HostedProjectId,
|
||||
hosted_project_id: ProjectId,
|
||||
app_state: Arc<AppState>,
|
||||
cx: &mut AppContext,
|
||||
) -> Task<Result<()>> {
|
||||
|
Loading…
Reference in New Issue
Block a user