You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.2 KiB
115 lines
3.2 KiB
use crate::api::{APIError, CurrentUser, MapToAPIError, PolicyError::*, API}; |
|
use crate::db_conn::Db; |
|
use crate::models::*; |
|
use crate::rds_conn::RdsConn; |
|
use crate::rds_models::*; |
|
use chrono::NaiveDateTime; |
|
use rocket::form::Form; |
|
use rocket::serde::{ |
|
json::{json, Value}, |
|
Serialize, |
|
}; |
|
use std::collections::HashMap; |
|
|
|
#[derive(FromForm)] |
|
pub struct CommentInput { |
|
pid: i32, |
|
#[field(validate = len(1..4097))] |
|
text: String, |
|
use_title: Option<i8>, |
|
} |
|
|
|
#[derive(Serialize)] |
|
#[serde(crate = "rocket::serde")] |
|
pub struct CommentOutput { |
|
cid: i32, |
|
text: String, |
|
can_del: bool, |
|
name_id: i32, |
|
is_tmp: bool, |
|
create_time: NaiveDateTime, |
|
// for old version frontend |
|
timestamp: i64, |
|
} |
|
|
|
pub fn c2output<'r>(p: &'r Post, cs: &Vec<Comment>, user: &CurrentUser) -> Vec<CommentOutput> { |
|
let mut hash2id = HashMap::<&String, i32>::from([(&p.author_hash, 0)]); |
|
cs.iter() |
|
.filter_map(|c| { |
|
let name_id: i32 = match hash2id.get(&c.author_hash) { |
|
Some(id) => *id, |
|
None => { |
|
let x = hash2id.len().try_into().unwrap(); |
|
hash2id.insert(&c.author_hash, x); |
|
x |
|
} |
|
}; |
|
if c.is_deleted { |
|
// TODO: block |
|
None |
|
} else { |
|
Some(CommentOutput { |
|
cid: c.id, |
|
text: format!("{}{}", if c.is_tmp { "[tmp]\n" } else { "" }, c.content), |
|
can_del: user.is_admin || c.author_hash == user.namehash, |
|
name_id: name_id, |
|
is_tmp: c.is_tmp, |
|
create_time: c.create_time, |
|
timestamp: c.create_time.timestamp(), |
|
}) |
|
} |
|
}) |
|
.collect() |
|
} |
|
|
|
#[get("/getcomment?<pid>")] |
|
pub async fn get_comment(pid: i32, user: CurrentUser, db: Db, rconn: RdsConn) -> API<Value> { |
|
let p = Post::get(&db, pid).await.m()?; |
|
if p.is_deleted { |
|
return Err(APIError::PcError(IsDeleted)); |
|
} |
|
let pid = p.id; |
|
let cs = Comment::gets_by_post_id(&db, pid).await.m()?; |
|
let data = c2output(&p, &cs, &user); |
|
|
|
Ok(json!({ |
|
"code": 0, |
|
"data": data, |
|
"n_attentions": p.n_attentions, |
|
// for old version frontend |
|
"likenum": p.n_attentions, |
|
"attention": Attention::init(&user.namehash, rconn.clone()).has(p.id).await.m()? , |
|
})) |
|
} |
|
|
|
#[post("/docomment", data = "<ci>")] |
|
pub async fn add_comment( |
|
ci: Form<CommentInput>, |
|
user: CurrentUser, |
|
db: Db, |
|
rconn: RdsConn, |
|
) -> API<Value> { |
|
let p = Post::get(&db, ci.pid).await.m()?; |
|
Comment::create( |
|
&db, |
|
NewComment { |
|
content: ci.text.to_string(), |
|
author_hash: user.namehash.to_string(), |
|
author_title: "".to_string(), |
|
is_tmp: user.id.is_none(), |
|
post_id: ci.pid, |
|
}, |
|
) |
|
.await |
|
.m()?; |
|
p.change_n_comments(&db, 1).await.m()?; |
|
// auto attention after comment |
|
let mut att = Attention::init(&user.namehash, rconn); |
|
if !att.has(p.id).await.m()? { |
|
att.add(p.id).await.m()?; |
|
p.change_n_attentions(&db, 1).await.m()?; |
|
} |
|
Ok(json!({ |
|
"code": 0 |
|
})) |
|
}
|
|
|