add: user follow requests
add: nsfw questions fix: inherit nsfw status from questions fix: inherit community from questions
This commit is contained in:
parent
d6c7372610
commit
ad17acec98
24 changed files with 492 additions and 59 deletions
|
@ -621,7 +621,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
if !question.is_global {
|
||||
self.delete_request(question.owner, question.id, &owner)
|
||||
self.delete_request(question.owner, question.id, &owner, false)
|
||||
.await?;
|
||||
} else {
|
||||
self.incr_question_answer_count(data.context.answering)
|
||||
|
@ -629,15 +629,23 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// create notification for question owner
|
||||
self.create_notification(Notification::new(
|
||||
"Your question has received a new answer!".to_string(),
|
||||
format!(
|
||||
"[@{}](/api/v1/auth/user/find/{}) has answered your [question](/question/{}).",
|
||||
owner.username, owner.id, question.id
|
||||
),
|
||||
question.owner,
|
||||
))
|
||||
.await?;
|
||||
// (if the current user isn't the owner)
|
||||
if question.owner != data.owner {
|
||||
self.create_notification(Notification::new(
|
||||
"Your question has received a new answer!".to_string(),
|
||||
format!(
|
||||
"[@{}](/api/v1/auth/user/find/{}) has answered your [question](/question/{}).",
|
||||
owner.username, owner.id, question.id
|
||||
),
|
||||
question.owner,
|
||||
))
|
||||
.await?;
|
||||
}
|
||||
|
||||
// inherit nsfw status if we didn't get it from the community
|
||||
if question.context.is_nsfw {
|
||||
data.context.is_nsfw = question.context.is_nsfw;
|
||||
}
|
||||
}
|
||||
|
||||
// check if we're reposting a post
|
||||
|
|
|
@ -37,6 +37,8 @@ impl DataManager {
|
|||
// likes
|
||||
likes: get!(x->8(i32)) as isize,
|
||||
dislikes: get!(x->9(i32)) as isize,
|
||||
// ...
|
||||
context: serde_json::from_str(&get!(x->10(String))).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,6 +302,9 @@ impl DataManager {
|
|||
{
|
||||
return Err(Error::QuestionsDisabled);
|
||||
}
|
||||
|
||||
// inherit nsfw status
|
||||
data.context.is_nsfw = community.context.is_nsfw;
|
||||
} else {
|
||||
let receiver = self.get_user_by_id(data.receiver).await?;
|
||||
|
||||
|
@ -323,7 +328,7 @@ impl DataManager {
|
|||
|
||||
let res = execute!(
|
||||
&conn,
|
||||
"INSERT INTO questions VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
"INSERT INTO questions VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
|
||||
params![
|
||||
&(data.id as i64),
|
||||
&(data.created as i64),
|
||||
|
@ -334,7 +339,8 @@ impl DataManager {
|
|||
&0_i32,
|
||||
&(data.community as i64),
|
||||
&0_i32,
|
||||
&0_i32
|
||||
&0_i32,
|
||||
&serde_json::to_string(&data.context).unwrap()
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -404,7 +410,7 @@ impl DataManager {
|
|||
{
|
||||
// requests are also deleted when a post is created answering the given question
|
||||
// (unless the question is global)
|
||||
self.delete_request(y.owner, y.id, user).await?;
|
||||
self.delete_request(y.owner, y.id, user, false).await?;
|
||||
}
|
||||
|
||||
// delete all posts answering question
|
||||
|
|
|
@ -119,13 +119,21 @@ impl DataManager {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_request(&self, id: usize, linked_asset: usize, user: &User) -> Result<()> {
|
||||
pub async fn delete_request(
|
||||
&self,
|
||||
id: usize,
|
||||
linked_asset: usize,
|
||||
user: &User,
|
||||
force: bool,
|
||||
) -> Result<()> {
|
||||
let y = self
|
||||
.get_request_by_id_linked_asset(id, linked_asset)
|
||||
.await?;
|
||||
|
||||
if user.id != y.owner && !user.permissions.check(FinePermission::MANAGE_REQUESTS) {
|
||||
return Err(Error::NotAllowed);
|
||||
if !force {
|
||||
if user.id != y.owner && !user.permissions.check(FinePermission::MANAGE_REQUESTS) {
|
||||
return Err(Error::NotAllowed);
|
||||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
|
@ -133,13 +141,21 @@ impl DataManager {
|
|||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
||||
let res = execute!(&conn, "DELETE FROM requests WHERE id = $1", &[&(id as i64)]);
|
||||
let res = execute!(
|
||||
&conn,
|
||||
"DELETE FROM requests WHERE id = $1",
|
||||
&[&(y.id as i64)]
|
||||
);
|
||||
|
||||
if let Err(e) = res {
|
||||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.request:{}", id)).await;
|
||||
self.2.remove(format!("atto.request:{}", y.id)).await;
|
||||
|
||||
self.2
|
||||
.remove(format!("atto.request:{}:{}", id, linked_asset))
|
||||
.await;
|
||||
|
||||
// decr request count
|
||||
let owner = self.get_user_by_id(y.owner).await?;
|
||||
|
@ -159,7 +175,8 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
self.delete_request(x.id, x.linked_asset, user).await?;
|
||||
self.delete_request(x.id, x.linked_asset, user, false)
|
||||
.await?;
|
||||
|
||||
// delete question
|
||||
if x.action_type == ActionType::Answer {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use crate::model::auth::FollowResult;
|
||||
use crate::model::requests::{ActionRequest, ActionType};
|
||||
use crate::model::{Error, Result, auth::User, auth::UserFollow, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
|
||||
|
@ -219,7 +221,26 @@ impl DataManager {
|
|||
///
|
||||
/// # Arguments
|
||||
/// * `data` - a mock [`UserFollow`] object to insert
|
||||
pub async fn create_userfollow(&self, data: UserFollow) -> Result<()> {
|
||||
/// * `force` - if we should skip the request stage
|
||||
pub async fn create_userfollow(&self, data: UserFollow, force: bool) -> Result<FollowResult> {
|
||||
if !force {
|
||||
let other_user = self.get_user_by_id(data.receiver).await?;
|
||||
|
||||
if other_user.settings.private_profile {
|
||||
// send follow request instead
|
||||
self.create_request(ActionRequest::with_id(
|
||||
data.initiator,
|
||||
data.receiver,
|
||||
ActionType::Follow,
|
||||
data.receiver,
|
||||
))
|
||||
.await?;
|
||||
|
||||
return Ok(FollowResult::Requested);
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
|
@ -248,13 +269,16 @@ impl DataManager {
|
|||
self.incr_user_follower_count(data.receiver).await.unwrap();
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
Ok(FollowResult::Followed)
|
||||
}
|
||||
|
||||
pub async fn delete_userfollow(&self, id: usize, user: &User) -> Result<()> {
|
||||
let follow = self.get_userfollow_by_id(id).await?;
|
||||
|
||||
if (user.id != follow.initiator) && (user.id != follow.receiver) && !user.permissions.check(FinePermission::MANAGE_FOLLOWS) {
|
||||
if (user.id != follow.initiator)
|
||||
&& (user.id != follow.receiver)
|
||||
&& !user.permissions.check(FinePermission::MANAGE_FOLLOWS)
|
||||
{
|
||||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue