mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-27 12:54:42 +00:00
Track room participant role
(Also wire that through to project collaboration rules for now)
This commit is contained in:
parent
88ed5f7290
commit
bf304b3fe7
6 changed files with 73 additions and 9 deletions
|
@ -36,6 +36,7 @@ impl ParticipantLocation {
|
|||
pub struct LocalParticipant {
|
||||
pub projects: Vec<proto::ParticipantProject>,
|
||||
pub active_project: Option<WeakModel<Project>>,
|
||||
pub role: proto::ChannelRole,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -247,14 +247,18 @@ impl Room {
|
|||
let response = client.request(proto::CreateRoom {}).await?;
|
||||
let room_proto = response.room.ok_or_else(|| anyhow!("invalid room"))?;
|
||||
let room = cx.new_model(|cx| {
|
||||
Self::new(
|
||||
let mut room = Self::new(
|
||||
room_proto.id,
|
||||
None,
|
||||
response.live_kit_connection_info,
|
||||
client,
|
||||
user_store,
|
||||
cx,
|
||||
)
|
||||
);
|
||||
if let Some(participant) = room_proto.participants.first() {
|
||||
room.local_participant.role = participant.role()
|
||||
}
|
||||
room
|
||||
})?;
|
||||
|
||||
let initial_project_id = if let Some(initial_project) = initial_project {
|
||||
|
@ -710,7 +714,21 @@ impl Room {
|
|||
this.participant_user_ids.clear();
|
||||
|
||||
if let Some(participant) = local_participant {
|
||||
let role = participant.role();
|
||||
this.local_participant.projects = participant.projects;
|
||||
if this.local_participant.role != role {
|
||||
this.local_participant.role = role;
|
||||
// TODO!() this may be better done using optional replica ids instead.
|
||||
// (though need to figure out how to handle promotion? join and leave the project?)
|
||||
this.joined_projects.retain(|project| {
|
||||
if let Some(project) = project.upgrade() {
|
||||
project.update(cx, |project, _| project.set_role(role));
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.local_participant.projects.clear();
|
||||
}
|
||||
|
@ -1091,10 +1109,19 @@ impl Room {
|
|||
) -> Task<Result<Model<Project>>> {
|
||||
let client = self.client.clone();
|
||||
let user_store = self.user_store.clone();
|
||||
let role = self.local_participant.role;
|
||||
cx.emit(Event::RemoteProjectJoined { project_id: id });
|
||||
cx.spawn(move |this, mut cx| async move {
|
||||
let project =
|
||||
Project::remote(id, client, user_store, language_registry, fs, cx.clone()).await?;
|
||||
let project = Project::remote(
|
||||
id,
|
||||
client,
|
||||
user_store,
|
||||
language_registry,
|
||||
fs,
|
||||
role,
|
||||
cx.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.joined_projects.retain(|project| {
|
||||
|
|
|
@ -165,15 +165,16 @@ impl Database {
|
|||
if role.is_none() || role == Some(ChannelRole::Banned) {
|
||||
Err(anyhow!("not allowed"))?
|
||||
}
|
||||
let role = role.unwrap();
|
||||
|
||||
let live_kit_room = format!("channel-{}", nanoid::nanoid!(30));
|
||||
let room_id = self
|
||||
.get_or_create_channel_room(channel_id, &live_kit_room, environment, &*tx)
|
||||
.await?;
|
||||
|
||||
self.join_channel_room_internal(room_id, user_id, connection, &*tx)
|
||||
self.join_channel_room_internal(room_id, user_id, connection, role, &*tx)
|
||||
.await
|
||||
.map(|jr| (jr, accept_invite_result, role.unwrap()))
|
||||
.map(|jr| (jr, accept_invite_result, role))
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -131,7 +131,12 @@ impl Database {
|
|||
connection.owner_id as i32,
|
||||
))),
|
||||
participant_index: ActiveValue::set(Some(0)),
|
||||
..Default::default()
|
||||
role: ActiveValue::set(Some(ChannelRole::Admin)),
|
||||
|
||||
id: ActiveValue::NotSet,
|
||||
location_kind: ActiveValue::NotSet,
|
||||
location_project_id: ActiveValue::NotSet,
|
||||
initial_project_id: ActiveValue::NotSet,
|
||||
}
|
||||
.insert(&*tx)
|
||||
.await?;
|
||||
|
@ -162,7 +167,13 @@ impl Database {
|
|||
calling_connection.owner_id as i32,
|
||||
))),
|
||||
initial_project_id: ActiveValue::set(initial_project_id),
|
||||
..Default::default()
|
||||
role: ActiveValue::set(Some(ChannelRole::Member)),
|
||||
|
||||
id: ActiveValue::NotSet,
|
||||
answering_connection_id: ActiveValue::NotSet,
|
||||
answering_connection_server_id: ActiveValue::NotSet,
|
||||
location_kind: ActiveValue::NotSet,
|
||||
location_project_id: ActiveValue::NotSet,
|
||||
}
|
||||
.insert(&*tx)
|
||||
.await?;
|
||||
|
@ -384,6 +395,7 @@ impl Database {
|
|||
room_id: RoomId,
|
||||
user_id: UserId,
|
||||
connection: ConnectionId,
|
||||
role: ChannelRole,
|
||||
tx: &DatabaseTransaction,
|
||||
) -> Result<JoinRoom> {
|
||||
let participant_index = self
|
||||
|
@ -404,7 +416,11 @@ impl Database {
|
|||
connection.owner_id as i32,
|
||||
))),
|
||||
participant_index: ActiveValue::Set(Some(participant_index)),
|
||||
..Default::default()
|
||||
role: ActiveValue::set(Some(role)),
|
||||
id: ActiveValue::NotSet,
|
||||
location_kind: ActiveValue::NotSet,
|
||||
location_project_id: ActiveValue::NotSet,
|
||||
initial_project_id: ActiveValue::NotSet,
|
||||
}])
|
||||
.on_conflict(
|
||||
OnConflict::columns([room_participant::Column::UserId])
|
||||
|
@ -413,6 +429,7 @@ impl Database {
|
|||
room_participant::Column::AnsweringConnectionServerId,
|
||||
room_participant::Column::AnsweringConnectionLost,
|
||||
room_participant::Column::ParticipantIndex,
|
||||
room_participant::Column::Role,
|
||||
])
|
||||
.to_owned(),
|
||||
)
|
||||
|
|
|
@ -19,6 +19,7 @@ use project::{
|
|||
search::SearchQuery, DiagnosticSummary, FormatTrigger, HoverBlockKind, Project, ProjectPath,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use rpc::proto::ChannelRole;
|
||||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use std::{
|
||||
|
@ -3550,6 +3551,7 @@ async fn test_leaving_project(
|
|||
client_b.user_store().clone(),
|
||||
client_b.language_registry().clone(),
|
||||
FakeFs::new(cx.background_executor().clone()),
|
||||
ChannelRole::Member,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
|
|
|
@ -262,6 +262,8 @@ enum ProjectClientState {
|
|||
},
|
||||
Remote {
|
||||
sharing_has_stopped: bool,
|
||||
// todo!() this should be represented differently!
|
||||
is_read_only: bool,
|
||||
remote_id: u64,
|
||||
replica_id: ReplicaId,
|
||||
},
|
||||
|
@ -702,6 +704,7 @@ impl Project {
|
|||
user_store: Model<UserStore>,
|
||||
languages: Arc<LanguageRegistry>,
|
||||
fs: Arc<dyn Fs>,
|
||||
role: proto::ChannelRole,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<Model<Self>> {
|
||||
client.authenticate_and_connect(true, &cx).await?;
|
||||
|
@ -757,6 +760,7 @@ impl Project {
|
|||
client: client.clone(),
|
||||
client_state: Some(ProjectClientState::Remote {
|
||||
sharing_has_stopped: false,
|
||||
is_read_only: false,
|
||||
remote_id,
|
||||
replica_id,
|
||||
}),
|
||||
|
@ -797,6 +801,7 @@ impl Project {
|
|||
prettiers_per_worktree: HashMap::default(),
|
||||
prettier_instances: HashMap::default(),
|
||||
};
|
||||
this.set_role(role);
|
||||
for worktree in worktrees {
|
||||
let _ = this.add_worktree(&worktree, cx);
|
||||
}
|
||||
|
@ -1619,6 +1624,13 @@ impl Project {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn set_role(&mut self, role: proto::ChannelRole) {
|
||||
if let Some(ProjectClientState::Remote { is_read_only, .. }) = &mut self.client_state {
|
||||
*is_read_only =
|
||||
!(role == proto::ChannelRole::Member || role == proto::ChannelRole::Admin)
|
||||
}
|
||||
}
|
||||
|
||||
fn disconnected_from_host_internal(&mut self, cx: &mut AppContext) {
|
||||
if let Some(ProjectClientState::Remote {
|
||||
sharing_has_stopped,
|
||||
|
@ -1672,6 +1684,10 @@ impl Project {
|
|||
|
||||
pub fn is_read_only(&self) -> bool {
|
||||
self.is_disconnected()
|
||||
|| match &self.client_state {
|
||||
Some(ProjectClientState::Remote { is_read_only, .. }) => *is_read_only,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_local(&self) -> bool {
|
||||
|
|
Loading…
Reference in a new issue