forked from jmug/stoatchat
Servers: Add new system messages.
This commit is contained in:
@@ -115,6 +115,20 @@ impl Channel {
|
||||
let id = self.id();
|
||||
let messages = get_collection("messages");
|
||||
|
||||
// Delete any invites.
|
||||
get_collection("invites")
|
||||
.delete_many(
|
||||
doc! {
|
||||
"channel": id
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "delete_many",
|
||||
with: "invites",
|
||||
})?;
|
||||
|
||||
// Check if there are any attachments we need to delete.
|
||||
let message_ids = messages
|
||||
.find(
|
||||
@@ -190,15 +204,45 @@ impl Channel {
|
||||
|
||||
// Remove from server object.
|
||||
if let Channel::TextChannel { server, .. } = &self {
|
||||
let server = Ref::from_unchecked(server.clone()).fetch_server().await?;
|
||||
let mut unset = doc! {};
|
||||
|
||||
if let Some(sys) = &server.system_messages {
|
||||
if let Some(cid) = &sys.user_joined {
|
||||
if id == cid {
|
||||
unset.insert("system_messages.user_joined", 1);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(cid) = &sys.user_left {
|
||||
if id == cid {
|
||||
unset.insert("system_messages.user_left", 1);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(cid) = &sys.user_kicked {
|
||||
if id == cid {
|
||||
unset.insert("system_messages.user_kicked", 1);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(cid) = &sys.user_banned {
|
||||
if id == cid {
|
||||
unset.insert("system_messages.user_banned", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get_collection("servers")
|
||||
.update_one(
|
||||
doc! {
|
||||
"_id": server
|
||||
"_id": server.id
|
||||
},
|
||||
doc! {
|
||||
"$pull": {
|
||||
"channels": id
|
||||
}
|
||||
},
|
||||
"$unset": unset
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
||||
@@ -26,8 +26,14 @@ pub enum SystemMessage {
|
||||
UserAdded { id: String, by: String },
|
||||
#[serde(rename = "user_remove")]
|
||||
UserRemove { id: String, by: String },
|
||||
#[serde(rename = "user_joined")]
|
||||
UserJoined { id: String },
|
||||
#[serde(rename = "user_left")]
|
||||
UserLeft { id: String },
|
||||
#[serde(rename = "user_kicked")]
|
||||
UserKicked { id: String },
|
||||
#[serde(rename = "user_banned")]
|
||||
UserBanned { id: String },
|
||||
#[serde(rename = "channel_renamed")]
|
||||
ChannelRenamed { name: String, by: String },
|
||||
#[serde(rename = "channel_description_changed")]
|
||||
|
||||
@@ -34,6 +34,20 @@ pub struct Ban {
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct SystemMessageChannels {
|
||||
pub user_joined: Option<String>,
|
||||
pub user_left: Option<String>,
|
||||
pub user_kicked: Option<String>,
|
||||
pub user_banned: Option<String>
|
||||
}
|
||||
|
||||
pub enum RemoveMember {
|
||||
Leave,
|
||||
Kick,
|
||||
Ban
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Server {
|
||||
#[serde(rename = "_id")]
|
||||
@@ -46,6 +60,8 @@ pub struct Server {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub description: Option<String>,
|
||||
pub channels: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub system_messages: Option<SystemMessageChannels>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub icon: Option<File>,
|
||||
@@ -296,10 +312,19 @@ impl Server {
|
||||
}
|
||||
.publish(self.id.clone());
|
||||
|
||||
if let Some(channels) = &self.system_messages {
|
||||
if let Some(cid) = &channels.user_joined {
|
||||
let channel = Ref::from_unchecked(cid.clone()).fetch_channel().await?;
|
||||
Content::SystemMessage(SystemMessage::UserJoined { id: id.to_string() })
|
||||
.send_as_system(&channel)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove_member(&self, id: &str) -> Result<()> {
|
||||
pub async fn remove_member(&self, id: &str, removal: RemoveMember) -> Result<()> {
|
||||
let result = get_collection("server_members")
|
||||
.delete_one(
|
||||
doc! {
|
||||
@@ -322,6 +347,39 @@ impl Server {
|
||||
user: id.to_string(),
|
||||
}
|
||||
.publish(self.id.clone());
|
||||
|
||||
if let Some(channels) = &self.system_messages {
|
||||
let message = match removal {
|
||||
RemoveMember::Leave => {
|
||||
if let Some(cid) = &channels.user_left {
|
||||
Some((cid.clone(), SystemMessage::UserLeft { id: id.to_string() }))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
RemoveMember::Kick => {
|
||||
if let Some(cid) = &channels.user_kicked {
|
||||
Some((cid.clone(), SystemMessage::UserKicked { id: id.to_string() }))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
RemoveMember::Ban => {
|
||||
if let Some(cid) = &channels.user_banned {
|
||||
Some((cid.clone(), SystemMessage::UserBanned { id: id.to_string() }))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some((cid, message)) = message {
|
||||
let channel = Ref::from_unchecked(cid).fetch_channel().await?;
|
||||
Content::SystemMessage(message)
|
||||
.send_as_system(&channel)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -49,5 +49,5 @@ pub async fn req(user: User, server: Ref, target: Ref, data: Json<Data>) -> Resu
|
||||
with: "server_ban",
|
||||
})?;
|
||||
|
||||
server.remove_member(&target.id).await
|
||||
server.remove_member(&target.id, RemoveMember::Ban).await
|
||||
}
|
||||
|
||||
@@ -25,5 +25,5 @@ pub async fn req(user: User, target: Ref, member: String) -> Result<()> {
|
||||
return Err(Error::MissingPermission);
|
||||
}
|
||||
|
||||
target.remove_member(&member.id.user).await
|
||||
target.remove_member(&member.id.user, RemoveMember::Kick).await
|
||||
}
|
||||
|
||||
@@ -52,6 +52,14 @@ pub async fn req(user: User, info: Json<Data>) -> Result<JsonValue> {
|
||||
name: info.name,
|
||||
description: info.description,
|
||||
channels: vec![cid.clone()],
|
||||
system_messages: Some(
|
||||
SystemMessageChannels {
|
||||
user_joined: Some(cid.clone()),
|
||||
user_left: Some(cid.clone()),
|
||||
user_kicked: Some(cid.clone()),
|
||||
user_banned: Some(cid.clone())
|
||||
}
|
||||
),
|
||||
|
||||
icon: None,
|
||||
banner: None,
|
||||
|
||||
@@ -18,6 +18,6 @@ pub async fn req(user: User, target: Ref) -> Result<()> {
|
||||
if user.id == target.owner {
|
||||
target.delete().await
|
||||
} else {
|
||||
target.remove_member(&user.id).await
|
||||
target.remove_member(&user.id, RemoveMember::Leave).await
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user