diff --git a/Cargo.lock b/Cargo.lock index c1b017ad..c4e2f1dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2943,6 +2943,7 @@ dependencies = [ "async-std", "async-trait", "bitfield", + "bson 2.1.0", "futures", "impl_ops", "lazy_static", diff --git a/src/routes/channels/message_edit.rs b/src/routes/channels/message_edit.rs index 13e4d621..27b33504 100644 --- a/src/routes/channels/message_edit.rs +++ b/src/routes/channels/message_edit.rs @@ -1,7 +1,12 @@ -use revolt_quark::{EmptyResponse, Result}; +use revolt_quark::{ + bson::DateTime, + models::message::{PartialMessage, SendableEmbed}, + models::{message::Content, Message, User}, + types::january::Embed, + Db, Error, Ref, Result, +}; use chrono::Utc; -use mongodb::bson::{doc, to_document, Bson, Document}; use rocket::serde::json::Json; use serde::{Deserialize, Serialize}; use validator::Validate; @@ -10,15 +15,65 @@ use validator::Validate; pub struct Data { #[validate(length(min = 1, max = 2000))] content: Option, - // #[validate(length(min = 0, max = 10))] - // embeds: Option> + #[validate(length(min = 0, max = 10))] + embeds: Option>, } #[patch("//messages/", data = "")] pub async fn req( - /*user: UserRef, target: Ref, msg: Ref,*/ target: String, - msg: String, + db: &Db, + user: User, + target: String, + msg: Ref, edit: Json, -) -> Result { - todo!() +) -> Result> { + let edit = edit.into_inner(); + edit.validate() + .map_err(|error| Error::FailedValidation { error })?; + + let mut message = msg.as_message(db).await?; + if message.channel != target { + return Err(Error::NotFound); + } + + if message.author != user.id { + return Err(Error::CannotEditMessage); + } + + message.edited = Some(DateTime::from_chrono(Utc::now())); + let mut partial = PartialMessage { + edited: message.edited, + ..Default::default() + }; + + // 1. Handle content update + if let Some(content) = edit.content { + message.content = Content::Text(content); + partial.content = Some(message.content.clone()); + } + + // 2. Clear any auto generated embeds + let mut new_embeds: Vec = vec![]; + if let Some(embeds) = &message.embeds { + for embed in embeds { + if let Embed::Text(embed) = embed { + new_embeds.push(Embed::Text(embed.clone())) + } + } + } + + // 3. Replace if we are given new embeds + if let Some(embeds) = edit.embeds { + new_embeds.clear(); + + for embed in embeds { + new_embeds.push(embed.clone().into_embed(db, message.id.clone()).await?); + } + } + + message.embeds = Some(new_embeds); + partial.embeds = message.embeds.clone(); + + db.update_message(&message.id, &partial, vec![]).await?; + Ok(Json(message)) } diff --git a/src/routes/channels/message_query.rs b/src/routes/channels/message_query.rs index 6af42d24..ce90530c 100644 --- a/src/routes/channels/message_query.rs +++ b/src/routes/channels/message_query.rs @@ -3,8 +3,7 @@ use revolt_quark::{ message::{BulkMessageResponse, MessageSort}, User, }, - perms, - Db, Error, Ref, Result, + perms, Db, Error, Ref, Result, }; use rocket::serde::json::Json; use serde::{Deserialize, Serialize}; @@ -65,6 +64,8 @@ pub async fn req( let messages = db .fetch_messages(channel.id(), limit, before, after, sort, nearby) .await?; - - BulkMessageResponse::transform(db, &channel, messages, include_users).await.map(Json) + + BulkMessageResponse::transform(db, &channel, messages, include_users) + .await + .map(Json) } diff --git a/src/routes/channels/message_query_stale.rs b/src/routes/channels/message_query_stale.rs index ad16747c..38aaca96 100644 --- a/src/routes/channels/message_query_stale.rs +++ b/src/routes/channels/message_query_stale.rs @@ -1,7 +1,5 @@ -use revolt_quark::{Error, Result}; +use revolt_quark::{models::User, Ref, Result}; -use futures::StreamExt; -use mongodb::bson::{doc, from_document}; use rocket::serde::json::{Json, Value}; use serde::{Deserialize, Serialize}; @@ -10,10 +8,7 @@ pub struct Options { ids: Vec, } -#[post("//messages/stale", data = "")] -pub async fn req( - /*user: UserRef, target: Ref,*/ target: String, - data: Json, -) -> Result { - todo!() +#[post("/<_target>/messages/stale", data = "<_data>")] +pub async fn req(_user: User, _target: Ref, _data: Json) -> Result { + unimplemented!() } diff --git a/src/routes/channels/message_search.rs b/src/routes/channels/message_search.rs index 89da03d2..1996b157 100644 --- a/src/routes/channels/message_search.rs +++ b/src/routes/channels/message_search.rs @@ -1,4 +1,10 @@ -use revolt_quark::{models::{User, message::{MessageSort, BulkMessageResponse}}, Ref, Error, Result, Db, perms}; +use revolt_quark::{ + models::{ + message::{BulkMessageResponse, MessageSort}, + User, + }, + perms, Db, Error, Ref, Result, +}; use rocket::serde::json::Json; use serde::{Deserialize, Serialize}; @@ -21,7 +27,12 @@ pub struct Options { } #[post("//search", data = "")] -pub async fn req(db: &Db, user: User, target: Ref, options: Json) -> Result> { +pub async fn req( + db: &Db, + user: User, + target: Ref, + options: Json, +) -> Result> { let options = options.into_inner(); options .validate() @@ -43,12 +54,14 @@ pub async fn req(db: &Db, user: User, target: Ref, options: Json) -> Re before, after, sort, - include_users + include_users, } = options; let messages = db .search_messages(channel.id(), &query, limit, before, after, sort) .await?; - - BulkMessageResponse::transform(db, &channel, messages, include_users).await.map(Json) + + BulkMessageResponse::transform(db, &channel, messages, include_users) + .await + .map(Json) }