Servers: Core objects required. Includes creation. Bump version to 0.5.0.

This commit is contained in:
Paul
2021-06-01 17:09:31 +01:00
parent a4c1fee4cc
commit bff72fa6c3
23 changed files with 415 additions and 59 deletions

View File

@@ -39,6 +39,12 @@ pub enum RemoveChannelField {
Icon,
}
#[derive(Serialize, Deserialize, Debug)]
pub enum RemoveServerField {
Icon,
Banner,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type")]
pub enum ClientboundNotification {
@@ -46,6 +52,7 @@ pub enum ClientboundNotification {
Authenticated,
Ready {
users: Vec<User>,
servers: Vec<Server>,
channels: Vec<Channel>,
},
@@ -67,6 +74,9 @@ pub enum ClientboundNotification {
#[serde(skip_serializing_if = "Option::is_none")]
clear: Option<RemoveChannelField>,
},
ChannelDelete {
id: String,
},
ChannelGroupJoin {
id: String,
user: String,
@@ -75,9 +85,6 @@ pub enum ClientboundNotification {
id: String,
user: String,
},
ChannelDelete {
id: String,
},
ChannelStartTyping {
id: String,
user: String,
@@ -87,6 +94,25 @@ pub enum ClientboundNotification {
user: String,
},
ServerCreate(Server),
ServerUpdate {
id: String,
data: JsonValue,
#[serde(skip_serializing_if = "Option::is_none")]
clear: Option<RemoveServerField>,
},
ServerDelete {
id: String,
},
ServerMemberJoin {
id: String,
user: String,
},
ServerMemberLeave {
id: String,
user: String,
},
UserUpdate {
id: String,
data: JsonValue,
@@ -104,8 +130,8 @@ pub enum ClientboundNotification {
},
UserSettingsUpdate {
id: String,
update: JsonValue
}
update: JsonValue,
},
}
impl ClientboundNotification {
@@ -137,6 +163,12 @@ pub fn prehandle_hook(notification: &ClientboundNotification) {
}
}
}
ClientboundNotification::ServerMemberJoin { id, user } => {
subscribe_if_exists(user.clone(), id.clone()).ok();
}
ClientboundNotification::ServerCreate(server) => {
subscribe_if_exists(server.owner.clone(), server.id.clone()).ok();
}
ClientboundNotification::UserRelationship { id, user, status } => {
if status != &RelationshipStatus::None {
subscribe_if_exists(id.clone(), user.id.clone()).ok();
@@ -151,6 +183,21 @@ pub fn posthandle_hook(notification: &ClientboundNotification) {
ClientboundNotification::ChannelDelete { id } => {
get_hive().hive.drop_topic(&id).ok();
}
ClientboundNotification::ChannelGroupLeave { id, user } => {
get_hive()
.hive
.unsubscribe(&user.to_string(), &id.to_string())
.ok();
}
ClientboundNotification::ServerDelete { id } => {
get_hive().hive.drop_topic(&id).ok();
}
ClientboundNotification::ServerMemberLeave { id, user } => {
get_hive()
.hive
.unsubscribe(&user.to_string(), &id.to_string())
.ok();
}
ClientboundNotification::UserRelationship { id, user, status } => {
if status == &RelationshipStatus::None {
get_hive()
@@ -159,12 +206,6 @@ pub fn posthandle_hook(notification: &ClientboundNotification) {
.ok();
}
}
ClientboundNotification::ChannelGroupLeave { id, user } => {
get_hive()
.hive
.unsubscribe(&user.to_string(), &id.to_string())
.ok();
}
_ => {}
}
}

View File

@@ -6,7 +6,7 @@ use crate::{
util::result::{Error, Result},
};
use futures::StreamExt;
use mongodb::bson::{doc, from_document};
use mongodb::bson::{doc, from_document, Document};
pub async fn generate_ready(mut user: User) -> Result<ClientboundNotification> {
let mut user_ids: HashSet<String> = HashSet::new();
@@ -19,10 +19,68 @@ pub async fn generate_ready(mut user: User) -> Result<ClientboundNotification> {
);
}
let server_ids = get_collection("server_members")
.find(
doc! {
"_id.user": &user.id
},
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "find",
with: "server_members",
})?
.filter_map(async move |s| s.ok())
.collect::<Vec<Document>>()
.await
.into_iter()
.filter_map(|x| {
x.get_document("_id")
.ok()
.map(|i| i.get_str("server").ok().map(|x| x.to_string()))
})
.flatten()
.collect::<Vec<String>>();
let mut cursor = get_collection("servers")
.find(
doc! {
"_id": {
"$in": server_ids
}
},
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "find",
with: "servers",
})?;
let mut servers = vec![];
let mut channel_ids = vec![];
while let Some(result) = cursor.next().await {
if let Ok(doc) = result {
let server: Server = from_document(doc).map_err(|_| Error::DatabaseError {
operation: "from_document",
with: "server",
})?;
channel_ids.extend(server.channels.iter().cloned());
servers.push(server);
}
}
let mut cursor = get_collection("channels")
.find(
doc! {
"$or": [
{
"_id": {
"$in": channel_ids
}
},
{
"channel_type": "SavedMessages",
"user": &user.id
@@ -75,5 +133,9 @@ pub async fn generate_ready(mut user: User) -> Result<ClientboundNotification> {
user.online = Some(true);
users.push(user);
Ok(ClientboundNotification::Ready { users, channels })
Ok(ClientboundNotification::Ready {
users,
servers,
channels,
})
}

View File

@@ -45,5 +45,7 @@ pub async fn generate_subscriptions(user: &User) -> Result<(), String> {
}
}
// ! FIXME: fetch memberships for servers
Ok(())
}

View File

@@ -243,8 +243,8 @@ pub fn publish(ids: Vec<String>, notification: ClientboundNotification) {
for id in ids {
// Block certain notifications from reaching users that aren't meant to see them.
match &notification {
ClientboundNotification::UserRelationship { id: user_id, .. } |
ClientboundNotification::UserSettingsUpdate { id: user_id, .. } => {
ClientboundNotification::UserRelationship { id: user_id, .. }
| ClientboundNotification::UserSettingsUpdate { id: user_id, .. } => {
if &id != user_id {
continue;
}