forked from jmug/stoatchat
Channel subscription, message sending, channel delete.
This commit is contained in:
@@ -28,6 +28,14 @@ pub enum Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Channel {
|
impl Channel {
|
||||||
|
pub fn id(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Channel::SavedMessages { id, .. } => id,
|
||||||
|
Channel::DirectMessage { id, .. } => id,
|
||||||
|
Channel::Group { id, .. } => id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn save(&self) -> Result<()> {
|
pub async fn save(&self) -> Result<()> {
|
||||||
get_collection("channels")
|
get_collection("channels")
|
||||||
.insert_one(
|
.insert_one(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// use mongodb::bson::DateTime;
|
use crate::{database::*, notifications::events::ClientboundNotification, util::result::Result};
|
||||||
// use serde::{Deserialize, Serialize};
|
use mongodb::bson::{DateTime, to_bson};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/*#[derive(Serialize, Deserialize, Debug)]
|
/*#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct PreviousEntry {
|
pub struct PreviousEntry {
|
||||||
@@ -20,3 +21,36 @@ pub struct Message {
|
|||||||
|
|
||||||
pub previous_content: Vec<PreviousEntry>,
|
pub previous_content: Vec<PreviousEntry>,
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Message {
|
||||||
|
#[serde(rename = "_id")]
|
||||||
|
pub id: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub nonce: Option<String>,
|
||||||
|
pub channel: String,
|
||||||
|
pub author: String,
|
||||||
|
|
||||||
|
pub content: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub edited: Option<DateTime>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Message {
|
||||||
|
pub async fn send(self) -> Result<()> {
|
||||||
|
get_collection("messages")
|
||||||
|
.insert_one(
|
||||||
|
to_bson(&self).unwrap().as_document().unwrap().clone(),
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let channel = self.channel.clone();
|
||||||
|
ClientboundNotification::Message(self)
|
||||||
|
.publish(channel)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,6 +28,23 @@ pub async fn calculate(user: &User, target: &Channel) -> ChannelPermissions<[u32
|
|||||||
ChannelPermissions([ 0 ])
|
ChannelPermissions([ 0 ])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Channel::DirectMessage { recipients, .. } => {
|
||||||
|
if recipients.iter().find(|x| *x == &user.id).is_some() {
|
||||||
|
if let Some(recipient) = recipients
|
||||||
|
.iter()
|
||||||
|
.find(|x| *x != &user.id) {
|
||||||
|
let perms = super::user::calculate(&user, recipient).await;
|
||||||
|
|
||||||
|
if perms.get_send_message() {
|
||||||
|
return ChannelPermissions([ ChannelPermission::View + ChannelPermission::SendMessage ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ChannelPermissions([ ChannelPermission::View as u32 ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPermissions([ 0 ])
|
||||||
|
}
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ pub enum ClientboundNotification {
|
|||||||
channels: Vec<Channel>
|
channels: Vec<Channel>
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Message(Message),
|
||||||
|
|
||||||
/*MessageCreate {
|
/*MessageCreate {
|
||||||
id: String,
|
id: String,
|
||||||
nonce: Option<String>,
|
nonce: Option<String>,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
use crate::database::*;
|
use crate::database::*;
|
||||||
|
|
||||||
use super::hive::get_hive;
|
use futures::StreamExt;
|
||||||
|
use mongodb::bson::doc;
|
||||||
use hive_pubsub::PubSub;
|
use hive_pubsub::PubSub;
|
||||||
|
use super::hive::get_hive;
|
||||||
|
use mongodb::options::FindOptions;
|
||||||
|
|
||||||
pub async fn generate_subscriptions(user: &User) -> Result<(), String> {
|
pub async fn generate_subscriptions(user: &User) -> Result<(), String> {
|
||||||
let hive = get_hive();
|
let hive = get_hive();
|
||||||
@@ -13,5 +16,37 @@ pub async fn generate_subscriptions(user: &User) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut cursor = get_collection("channels")
|
||||||
|
.find(
|
||||||
|
doc! {
|
||||||
|
"$or": [
|
||||||
|
{
|
||||||
|
"type": "SavedMessages",
|
||||||
|
"user": &user.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "DirectMessage",
|
||||||
|
"recipients": &user.id,
|
||||||
|
"active": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Group",
|
||||||
|
"recipients": &user.id
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
FindOptions::builder()
|
||||||
|
.projection(doc! { "_id": 1 })
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|_| "Failed to fetch channels.".to_string())?;
|
||||||
|
|
||||||
|
while let Some(result) = cursor.next().await {
|
||||||
|
if let Ok(doc) = result {
|
||||||
|
hive.subscribe(user.id.clone(), doc.get_str("_id").unwrap().to_string())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
37
src/routes/channels/delete_channel.rs
Normal file
37
src/routes/channels/delete_channel.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
use crate::database::*;
|
||||||
|
use crate::util::result::{Error, Result};
|
||||||
|
|
||||||
|
use mongodb::bson::doc;
|
||||||
|
|
||||||
|
#[delete("/<target>")]
|
||||||
|
pub async fn req(user: User, target: Ref) -> Result<()> {
|
||||||
|
let target = target.fetch_channel().await?;
|
||||||
|
|
||||||
|
let perm = permissions::channel::calculate(&user, &target).await;
|
||||||
|
if !perm.get_view() {
|
||||||
|
Err(Error::LabelMe)?
|
||||||
|
}
|
||||||
|
|
||||||
|
match target {
|
||||||
|
Channel::SavedMessages { .. } => Err(Error::NoEffect),
|
||||||
|
Channel::DirectMessage { .. } => {
|
||||||
|
get_collection("channels")
|
||||||
|
.update_one(
|
||||||
|
doc! {
|
||||||
|
"_id": target.id()
|
||||||
|
},
|
||||||
|
doc! {
|
||||||
|
"$set": {
|
||||||
|
"active": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|_| Error::DatabaseError { operation: "update_one", with: "channel" })?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
_ => unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
use rocket::Route;
|
use rocket::Route;
|
||||||
|
|
||||||
mod fetch_channel;
|
mod fetch_channel;
|
||||||
|
mod delete_channel;
|
||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes![
|
routes![
|
||||||
fetch_channel::req
|
fetch_channel::req,
|
||||||
|
delete_channel::req
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user