feat(messages): implement message editing

This commit is contained in:
Paul Makles
2022-02-10 13:33:13 +00:00
parent a4cbbfea51
commit 57d114fee9
5 changed files with 91 additions and 26 deletions

1
Cargo.lock generated
View File

@@ -2943,6 +2943,7 @@ dependencies = [
"async-std",
"async-trait",
"bitfield",
"bson 2.1.0",
"futures",
"impl_ops",
"lazy_static",

View File

@@ -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<String>,
// #[validate(length(min = 0, max = 10))]
// embeds: Option<Vec<SendableEmbed>>
#[validate(length(min = 0, max = 10))]
embeds: Option<Vec<SendableEmbed>>,
}
#[patch("/<target>/messages/<msg>", data = "<edit>")]
pub async fn req(
/*user: UserRef, target: Ref, msg: Ref,*/ target: String,
msg: String,
db: &Db,
user: User,
target: String,
msg: Ref,
edit: Json<Data>,
) -> Result<EmptyResponse> {
todo!()
) -> Result<Json<Message>> {
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<Embed> = 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))
}

View File

@@ -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)
}

View File

@@ -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<String>,
}
#[post("/<target>/messages/stale", data = "<data>")]
pub async fn req(
/*user: UserRef, target: Ref,*/ target: String,
data: Json<Options>,
) -> Result<Value> {
todo!()
#[post("/<_target>/messages/stale", data = "<_data>")]
pub async fn req(_user: User, _target: Ref, _data: Json<Options>) -> Result<Value> {
unimplemented!()
}

View File

@@ -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("/<target>/search", data = "<options>")]
pub async fn req(db: &Db, user: User, target: Ref, options: Json<Options>) -> Result<Json<BulkMessageResponse>> {
pub async fn req(
db: &Db,
user: User,
target: Ref,
options: Json<Options>,
) -> Result<Json<BulkMessageResponse>> {
let options = options.into_inner();
options
.validate()
@@ -43,12 +54,14 @@ pub async fn req(db: &Db, user: User, target: Ref, options: Json<Options>) -> 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)
}