mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 05:26:59 +00:00
Post-handle hook, partial updates and group delete.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
use crate::database::*;
|
||||
use crate::notifications::events::ClientboundNotification;
|
||||
use crate::util::result::{Error, Result};
|
||||
use mongodb::bson::to_document;
|
||||
use mongodb::bson::{doc, to_document};
|
||||
use rocket_contrib::json::JsonValue;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
@@ -62,4 +63,50 @@ impl Channel {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn publish_update(&self, partial: JsonValue) -> Result<()> {
|
||||
let id = self.id().to_string();
|
||||
ClientboundNotification::ChannelUpdate(partial)
|
||||
.publish(id)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete(&self) -> Result<()> {
|
||||
let id = self.id();
|
||||
get_collection("messages")
|
||||
.delete_many(
|
||||
doc! {
|
||||
"channel": id
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "delete_many",
|
||||
with: "messages",
|
||||
})?;
|
||||
|
||||
get_collection("channels")
|
||||
.delete_one(
|
||||
doc! {
|
||||
"_id": id
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "delete_one",
|
||||
with: "channel",
|
||||
})?;
|
||||
|
||||
ClientboundNotification::ChannelDelete { id: id.to_string() }
|
||||
.publish(id.to_string())
|
||||
.await
|
||||
.ok();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,30 +3,11 @@ use crate::{
|
||||
notifications::events::ClientboundNotification,
|
||||
util::result::{Error, Result},
|
||||
};
|
||||
use mongodb::bson::{to_bson, DateTime};
|
||||
use mongodb::bson::{doc, to_bson, DateTime};
|
||||
use rocket_contrib::json::JsonValue;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ulid::Ulid;
|
||||
|
||||
/*#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct PreviousEntry {
|
||||
pub content: String,
|
||||
pub time: DateTime,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Message {
|
||||
#[serde(rename = "_id")]
|
||||
pub id: String,
|
||||
pub nonce: Option<String>,
|
||||
pub channel: String,
|
||||
pub author: String,
|
||||
|
||||
pub content: String,
|
||||
pub edited: Option<DateTime>,
|
||||
|
||||
pub previous_content: Vec<PreviousEntry>,
|
||||
}*/
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Message {
|
||||
#[serde(rename = "_id")]
|
||||
@@ -72,9 +53,9 @@ impl Message {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn publish_edit(self) -> Result<()> {
|
||||
pub async fn publish_update(&self, partial: JsonValue) -> Result<()> {
|
||||
let channel = self.channel.clone();
|
||||
ClientboundNotification::MessageEdit(self)
|
||||
ClientboundNotification::MessageUpdate(partial)
|
||||
.publish(channel)
|
||||
.await
|
||||
.ok();
|
||||
@@ -82,9 +63,22 @@ impl Message {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn publish_delete(self) -> Result<()> {
|
||||
pub async fn delete(&self) -> Result<()> {
|
||||
get_collection("messages")
|
||||
.delete_one(
|
||||
doc! {
|
||||
"_id": &self.id
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "delete_one",
|
||||
with: "message",
|
||||
})?;
|
||||
|
||||
let channel = self.channel.clone();
|
||||
ClientboundNotification::MessageDelete { id: self.id }
|
||||
ClientboundNotification::MessageDelete { id: self.id.clone() }
|
||||
.publish(channel)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use hive_pubsub::PubSub;
|
||||
use rauth::auth::Session;
|
||||
use rocket_contrib::json::JsonValue;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use snafu::Snafu;
|
||||
|
||||
@@ -38,12 +39,13 @@ pub enum ClientboundNotification {
|
||||
},
|
||||
|
||||
Message(Message),
|
||||
MessageEdit(Message),
|
||||
MessageUpdate(JsonValue),
|
||||
MessageDelete {
|
||||
id: String,
|
||||
},
|
||||
|
||||
ChannelCreate(Channel),
|
||||
ChannelUpdate(JsonValue),
|
||||
ChannelGroupJoin {
|
||||
id: String,
|
||||
user: String,
|
||||
@@ -52,6 +54,9 @@ pub enum ClientboundNotification {
|
||||
id: String,
|
||||
user: String,
|
||||
},
|
||||
ChannelDelete {
|
||||
id: String,
|
||||
},
|
||||
|
||||
UserRelationship {
|
||||
id: String,
|
||||
@@ -95,17 +100,31 @@ pub fn prehandle_hook(notification: &ClientboundNotification) {
|
||||
.unsubscribe(&user.to_string(), &id.to_string())
|
||||
.ok();
|
||||
}
|
||||
ClientboundNotification::UserRelationship { id, user, status } => match status {
|
||||
RelationshipStatus::None => {
|
||||
ClientboundNotification::UserRelationship { id, user, status } => {
|
||||
if status != &RelationshipStatus::None {
|
||||
subscribe_if_exists(id.clone(), user.clone()).ok();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn posthandle_hook(notification: &ClientboundNotification) {
|
||||
match ¬ification {
|
||||
ClientboundNotification::ChannelDelete { id } => {
|
||||
get_hive()
|
||||
.hive
|
||||
.drop_topic(&id)
|
||||
.ok();
|
||||
}
|
||||
ClientboundNotification::UserRelationship { id, user, status } => {
|
||||
if status == &RelationshipStatus::None {
|
||||
get_hive()
|
||||
.hive
|
||||
.unsubscribe(&id.to_string(), &user.to_string())
|
||||
.ok();
|
||||
}
|
||||
_ => {
|
||||
subscribe_if_exists(id.clone(), user.clone()).ok();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ static HIVE: OnceCell<Hive> = OnceCell::new();
|
||||
pub async fn init_hive() {
|
||||
let hive = MongodbPubSub::new(
|
||||
|ids, notification| {
|
||||
super::events::posthandle_hook(¬ification);
|
||||
|
||||
if let Ok(data) = to_string(¬ification) {
|
||||
debug!("Pushing out notification. {}", data);
|
||||
websocket::publish(ids, notification);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::database::*;
|
||||
use crate::util::result::{Error, Result};
|
||||
use crate::{database::*, notifications::events::ClientboundNotification};
|
||||
|
||||
use mongodb::bson::doc;
|
||||
|
||||
@@ -12,7 +12,7 @@ pub async fn req(user: User, target: Ref) -> Result<()> {
|
||||
Err(Error::LabelMe)?
|
||||
}
|
||||
|
||||
match target {
|
||||
match &target {
|
||||
Channel::SavedMessages { .. } => Err(Error::NoEffect),
|
||||
Channel::DirectMessage { .. } => {
|
||||
get_collection("channels")
|
||||
@@ -35,6 +35,77 @@ pub async fn req(user: User, target: Ref) -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
Channel::Group {
|
||||
id,
|
||||
owner,
|
||||
recipients,
|
||||
..
|
||||
} => {
|
||||
if &user.id == owner {
|
||||
if let Some(new_owner) = recipients.iter().find(|x| *x != &user.id) {
|
||||
get_collection("channels")
|
||||
.update_one(
|
||||
doc! {
|
||||
"_id": &id
|
||||
},
|
||||
doc! {
|
||||
"$set": {
|
||||
"owner": new_owner
|
||||
},
|
||||
"$pull": {
|
||||
"recipients": &user.id
|
||||
}
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "update_one",
|
||||
with: "channel",
|
||||
})?;
|
||||
|
||||
target.publish_update(json!({ "owner": new_owner })).await?;
|
||||
} else {
|
||||
return target.delete().await
|
||||
}
|
||||
} else {
|
||||
get_collection("channels")
|
||||
.update_one(
|
||||
doc! {
|
||||
"_id": &id
|
||||
},
|
||||
doc! {
|
||||
"$pull": {
|
||||
"recipients": &user.id
|
||||
}
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "update_one",
|
||||
with: "channel",
|
||||
})?;
|
||||
}
|
||||
|
||||
ClientboundNotification::ChannelGroupLeave {
|
||||
id: id.clone(),
|
||||
user: user.id.clone(),
|
||||
}
|
||||
.publish(id.clone())
|
||||
.await
|
||||
.ok();
|
||||
|
||||
Message::create(
|
||||
"00000000000000000000000000".to_string(),
|
||||
id.clone(),
|
||||
format!("<@{}> left the group.", user.id),
|
||||
)
|
||||
.publish()
|
||||
.await
|
||||
.ok();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,20 +20,5 @@ pub async fn req(user: User, target: Ref, msg: Ref) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
get_collection("messages")
|
||||
.delete_one(
|
||||
doc! {
|
||||
"_id": &message.id
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "delete_one",
|
||||
with: "message",
|
||||
})?;
|
||||
|
||||
message.publish_delete().await?;
|
||||
|
||||
Ok(())
|
||||
message.delete().await
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub async fn req(user: User, target: Ref, msg: Ref, edit: Json<Data>) -> Result<
|
||||
Err(Error::LabelMe)?
|
||||
}
|
||||
|
||||
let mut message = msg.fetch_message().await?;
|
||||
let message = msg.fetch_message().await?;
|
||||
if message.author != user.id {
|
||||
Err(Error::CannotEditMessage)?
|
||||
}
|
||||
@@ -50,9 +50,5 @@ pub async fn req(user: User, target: Ref, msg: Ref, edit: Json<Data>) -> Result<
|
||||
with: "message",
|
||||
})?;
|
||||
|
||||
message.content = edit.content.clone();
|
||||
message.edited = Some(DateTime(edited));
|
||||
message.publish_edit().await?;
|
||||
|
||||
Ok(())
|
||||
message.publish_update(json!({ "content": edit.content, "edited": DateTime(edited) })).await
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use rocket_contrib::json::JsonValue;
|
||||
#[get("/")]
|
||||
pub async fn root() -> JsonValue {
|
||||
json!({
|
||||
"revolt": "0.3.1-alpha.0",
|
||||
"revolt": "0.3.1",
|
||||
"features": {
|
||||
"registration": !*DISABLE_REGISTRATION,
|
||||
"captcha": {
|
||||
|
||||
Reference in New Issue
Block a user