Merge branch 'main' into notifications

This commit is contained in:
Max Brunsfeld 2023-10-18 17:20:04 -07:00
commit b07f9fe3b5
61 changed files with 3185 additions and 1148 deletions

View file

@ -9,7 +9,7 @@ use db::RELEASE_CHANNEL;
use futures::{channel::mpsc, future::Shared, Future, FutureExt, StreamExt};
use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, WeakModelHandle};
use rpc::{
proto::{self, ChannelEdge, ChannelPermission},
proto::{self, ChannelEdge, ChannelPermission, ChannelRole, ChannelVisibility},
TypedEnvelope,
};
use serde_derive::{Deserialize, Serialize};
@ -49,6 +49,7 @@ pub type ChannelData = (Channel, ChannelPath);
pub struct Channel {
pub id: ChannelId,
pub name: String,
pub visibility: proto::ChannelVisibility,
pub unseen_note_version: Option<(u64, clock::Global)>,
pub unseen_message_id: Option<u64>,
}
@ -79,7 +80,32 @@ pub struct ChannelPath(Arc<[ChannelId]>);
pub struct ChannelMembership {
pub user: Arc<User>,
pub kind: proto::channel_member::Kind,
pub admin: bool,
pub role: proto::ChannelRole,
}
impl ChannelMembership {
pub fn sort_key(&self) -> MembershipSortKey {
MembershipSortKey {
role_order: match self.role {
proto::ChannelRole::Admin => 0,
proto::ChannelRole::Member => 1,
proto::ChannelRole::Banned => 2,
proto::ChannelRole::Guest => 3,
},
kind_order: match self.kind {
proto::channel_member::Kind::Member => 0,
proto::channel_member::Kind::AncestorMember => 1,
proto::channel_member::Kind::Invitee => 2,
},
username_order: self.user.github_login.as_str(),
}
}
}
#[derive(PartialOrd, Ord, PartialEq, Eq)]
pub struct MembershipSortKey<'a> {
role_order: u8,
kind_order: u8,
username_order: &'a str,
}
pub enum ChannelEvent {
@ -475,7 +501,7 @@ impl ChannelStore {
insert_edge: parent_edge,
channel_permissions: vec![ChannelPermission {
channel_id,
is_admin: true,
role: ChannelRole::Admin.into(),
}],
..Default::default()
},
@ -547,11 +573,30 @@ impl ChannelStore {
})
}
pub fn set_channel_visibility(
&mut self,
channel_id: ChannelId,
visibility: ChannelVisibility,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
let client = self.client.clone();
cx.spawn(|_, _| async move {
let _ = client
.request(proto::SetChannelVisibility {
channel_id,
visibility: visibility.into(),
})
.await?;
Ok(())
})
}
pub fn invite_member(
&mut self,
channel_id: ChannelId,
user_id: UserId,
admin: bool,
role: proto::ChannelRole,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
if !self.outgoing_invites.insert((channel_id, user_id)) {
@ -565,7 +610,7 @@ impl ChannelStore {
.request(proto::InviteChannelMember {
channel_id,
user_id,
admin,
role: role.into(),
})
.await;
@ -609,11 +654,11 @@ impl ChannelStore {
})
}
pub fn set_member_admin(
pub fn set_member_role(
&mut self,
channel_id: ChannelId,
user_id: UserId,
admin: bool,
role: proto::ChannelRole,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
if !self.outgoing_invites.insert((channel_id, user_id)) {
@ -624,10 +669,10 @@ impl ChannelStore {
let client = self.client.clone();
cx.spawn(|this, mut cx| async move {
let result = client
.request(proto::SetChannelMemberAdmin {
.request(proto::SetChannelMemberRole {
channel_id,
user_id,
admin,
role: role.into(),
})
.await;
@ -716,8 +761,8 @@ impl ChannelStore {
.filter_map(|(user, member)| {
Some(ChannelMembership {
user,
admin: member.admin,
kind: proto::channel_member::Kind::from_i32(member.kind)?,
role: member.role(),
kind: member.kind(),
})
})
.collect())
@ -912,6 +957,7 @@ impl ChannelStore {
ix,
Arc::new(Channel {
id: channel.id,
visibility: channel.visibility(),
name: channel.name,
unseen_note_version: None,
unseen_message_id: None,
@ -978,7 +1024,7 @@ impl ChannelStore {
}
for permission in payload.channel_permissions {
if permission.is_admin {
if permission.role() == proto::ChannelRole::Admin {
self.channels_with_admin_privileges
.insert(permission.channel_id);
} else {

View file

@ -123,12 +123,15 @@ impl<'a> ChannelPathsInsertGuard<'a> {
pub fn insert(&mut self, channel_proto: proto::Channel) {
if let Some(existing_channel) = self.channels_by_id.get_mut(&channel_proto.id) {
Arc::make_mut(existing_channel).name = channel_proto.name;
let existing_channel = Arc::make_mut(existing_channel);
existing_channel.visibility = channel_proto.visibility();
existing_channel.name = channel_proto.name;
} else {
self.channels_by_id.insert(
channel_proto.id,
Arc::new(Channel {
id: channel_proto.id,
visibility: channel_proto.visibility(),
name: channel_proto.name,
unseen_note_version: None,
unseen_message_id: None,

View file

@ -3,7 +3,7 @@ use crate::channel_chat::ChannelChatEvent;
use super::*;
use client::{test::FakeServer, Client, UserStore};
use gpui::{AppContext, ModelHandle, TestAppContext};
use rpc::proto;
use rpc::proto::{self};
use settings::SettingsStore;
use util::http::FakeHttpClient;
@ -18,15 +18,17 @@ fn test_update_channels(cx: &mut AppContext) {
proto::Channel {
id: 1,
name: "b".to_string(),
visibility: proto::ChannelVisibility::Members as i32,
},
proto::Channel {
id: 2,
name: "a".to_string(),
visibility: proto::ChannelVisibility::Members as i32,
},
],
channel_permissions: vec![proto::ChannelPermission {
channel_id: 1,
is_admin: true,
role: proto::ChannelRole::Admin.into(),
}],
..Default::default()
},
@ -49,10 +51,12 @@ fn test_update_channels(cx: &mut AppContext) {
proto::Channel {
id: 3,
name: "x".to_string(),
visibility: proto::ChannelVisibility::Members as i32,
},
proto::Channel {
id: 4,
name: "y".to_string(),
visibility: proto::ChannelVisibility::Members as i32,
},
],
insert_edge: vec![
@ -92,14 +96,17 @@ fn test_dangling_channel_paths(cx: &mut AppContext) {
proto::Channel {
id: 0,
name: "a".to_string(),
visibility: proto::ChannelVisibility::Members as i32,
},
proto::Channel {
id: 1,
name: "b".to_string(),
visibility: proto::ChannelVisibility::Members as i32,
},
proto::Channel {
id: 2,
name: "c".to_string(),
visibility: proto::ChannelVisibility::Members as i32,
},
],
insert_edge: vec![
@ -114,7 +121,7 @@ fn test_dangling_channel_paths(cx: &mut AppContext) {
],
channel_permissions: vec![proto::ChannelPermission {
channel_id: 0,
is_admin: true,
role: proto::ChannelRole::Admin.into(),
}],
..Default::default()
},
@ -158,6 +165,7 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
channels: vec![proto::Channel {
id: channel_id,
name: "the-channel".to_string(),
visibility: proto::ChannelVisibility::Members as i32,
}],
..Default::default()
});