add: reposts/quotes pages
add: repost notification
This commit is contained in:
parent
41250ef7ed
commit
276f25a496
17 changed files with 601 additions and 50 deletions
|
@ -121,6 +121,7 @@ impl DataManager {
|
|||
pub async fn fill_posts(
|
||||
&self,
|
||||
posts: Vec<Post>,
|
||||
ignore_users: &Vec<usize>,
|
||||
) -> Result<Vec<(Post, User, Option<(User, Post)>, Option<(Question, User)>)>> {
|
||||
let mut out: Vec<(Post, User, Option<(User, Post)>, Option<(Question, User)>)> = Vec::new();
|
||||
|
||||
|
@ -128,6 +129,10 @@ impl DataManager {
|
|||
for post in posts {
|
||||
let owner = post.owner;
|
||||
|
||||
if ignore_users.contains(&owner) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(user) = users.get(&owner) {
|
||||
out.push((
|
||||
post.clone(),
|
||||
|
@ -155,6 +160,7 @@ impl DataManager {
|
|||
&self,
|
||||
posts: Vec<Post>,
|
||||
user_id: usize,
|
||||
ignore_users: &Vec<usize>,
|
||||
) -> Result<
|
||||
Vec<(
|
||||
Post,
|
||||
|
@ -177,6 +183,11 @@ impl DataManager {
|
|||
|
||||
for post in posts {
|
||||
let owner = post.owner;
|
||||
|
||||
if ignore_users.contains(&owner) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let community = post.community;
|
||||
|
||||
if let Some((user, community)) = seen_before.get(&(owner, community)) {
|
||||
|
@ -402,6 +413,82 @@ impl DataManager {
|
|||
Ok(res.unwrap())
|
||||
}
|
||||
|
||||
/// Get all quoting posts by the post their quoting.
|
||||
///
|
||||
/// Requires that the post has content. See [`Self::get_reposts_by_quoting`]
|
||||
/// for the no-content version.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - the ID of the post that is being quoted
|
||||
/// * `batch` - the limit of posts in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_quoting_posts_by_quoting(
|
||||
&self,
|
||||
id: usize,
|
||||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
||||
let res = query_rows!(
|
||||
&conn,
|
||||
"SELECT * FROM posts WHERE NOT content = '' AND context LIKE $1 ORDER BY created DESC LIMIT $2 OFFSET $3",
|
||||
params![
|
||||
&format!("%\"reposting\":{id}%"),
|
||||
&(batch as i64),
|
||||
&((page * batch) as i64)
|
||||
],
|
||||
|x| { Self::get_post_from_row(x) }
|
||||
);
|
||||
|
||||
if res.is_err() {
|
||||
return Err(Error::GeneralNotFound("post".to_string()));
|
||||
}
|
||||
|
||||
Ok(res.unwrap())
|
||||
}
|
||||
|
||||
/// Get all quoting posts by the post their quoting.
|
||||
///
|
||||
/// Requires that the post has no content. See [`Self::get_quoting_posts_by_quoting`]
|
||||
/// for the content-required version.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - the ID of the post that is being quoted
|
||||
/// * `batch` - the limit of posts in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_reposts_by_quoting(
|
||||
&self,
|
||||
id: usize,
|
||||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
||||
let res = query_rows!(
|
||||
&conn,
|
||||
"SELECT * FROM posts WHERE content = '' AND context LIKE $1 ORDER BY created DESC LIMIT $2 OFFSET $3",
|
||||
params![
|
||||
&format!("%\"reposting\":{id}%"),
|
||||
&(batch as i64),
|
||||
&((page * batch) as i64)
|
||||
],
|
||||
|x| { Self::get_post_from_row(x) }
|
||||
);
|
||||
|
||||
if res.is_err() {
|
||||
return Err(Error::GeneralNotFound("post".to_string()));
|
||||
}
|
||||
|
||||
Ok(res.unwrap())
|
||||
}
|
||||
|
||||
/// Get posts from all communities, sorted by likes.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -694,6 +781,25 @@ impl DataManager {
|
|||
{
|
||||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
// send notification
|
||||
// this would look better if rustfmt didn't give up on this line
|
||||
if owner.id != rt.owner {
|
||||
self.create_notification(
|
||||
Notification::new(
|
||||
format!(
|
||||
"[@{}](/api/v1/auth/user/find/{}) has [quoted](/post/{}) your [post](/post/{})",
|
||||
owner.username,
|
||||
owner.id,
|
||||
data.id,
|
||||
rt.id
|
||||
),
|
||||
format!("\"{}\"", data.content),
|
||||
rt.owner
|
||||
)
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
// check if the post we're replying to allows commments
|
||||
|
@ -729,8 +835,8 @@ impl DataManager {
|
|||
self.create_notification(Notification::new(
|
||||
"You've been mentioned in a post!".to_string(),
|
||||
format!(
|
||||
"[Somebody](/api/v1/auth/user/find/{}) mentioned you in their [post](/post/{}).",
|
||||
data.owner, data.id
|
||||
"[@{}](/api/v1/auth/user/find/{}) has mentioned you in their [post](/post/{}).",
|
||||
owner.username, owner.id, data.id
|
||||
),
|
||||
user.id,
|
||||
))
|
||||
|
|
|
@ -46,11 +46,19 @@ impl DataManager {
|
|||
auto_method!(get_question_by_id()@get_question_from_row -> "SELECT * FROM questions WHERE id = $1" --name="question" --returns=Question --cache-key-tmpl="atto.question:{}");
|
||||
|
||||
/// Fill the given vector of questions with their owner as well.
|
||||
pub async fn fill_questions(&self, questions: Vec<Question>) -> Result<Vec<(Question, User)>> {
|
||||
pub async fn fill_questions(
|
||||
&self,
|
||||
questions: Vec<Question>,
|
||||
ignore_users: &Vec<usize>,
|
||||
) -> Result<Vec<(Question, User)>> {
|
||||
let mut out: Vec<(Question, User)> = Vec::new();
|
||||
|
||||
let mut seen_users: HashMap<usize, User> = HashMap::new();
|
||||
for question in questions {
|
||||
if ignore_users.contains(&question.owner) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(ua) = seen_users.get(&question.owner) {
|
||||
out.push((question, ua.to_owned()));
|
||||
} else {
|
||||
|
|
|
@ -130,7 +130,8 @@ impl DataManager {
|
|||
.get_request_by_id_linked_asset(id, linked_asset)
|
||||
.await?;
|
||||
|
||||
if !force && user.id != y.owner && !user.permissions.check(FinePermission::MANAGE_REQUESTS) {
|
||||
if !force && user.id != y.owner && !user.permissions.check(FinePermission::MANAGE_REQUESTS)
|
||||
{
|
||||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use crate::model::{Error, Result, auth::User, auth::UserBlock, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, params};
|
||||
use crate::{auto_method, execute, get, params, query_row, query_rows};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
|
@ -75,6 +75,35 @@ impl DataManager {
|
|||
Ok(res.unwrap())
|
||||
}
|
||||
|
||||
/// Get the receiver of all user blocks for the given `initiator`.
|
||||
pub async fn get_userblocks_receivers(&self, initiator: usize) -> Vec<usize> {
|
||||
let conn = match self.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
|
||||
let res = query_rows!(
|
||||
&conn,
|
||||
"SELECT * FROM userblocks WHERE receiver = $1",
|
||||
&[&(initiator as i64)],
|
||||
|x| { Self::get_userblock_from_row(x) }
|
||||
);
|
||||
|
||||
if res.is_err() {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
// get receivers
|
||||
let mut out: Vec<usize> = Vec::new();
|
||||
|
||||
for b in res.unwrap() {
|
||||
out.push(b.receiver);
|
||||
}
|
||||
|
||||
// return
|
||||
out
|
||||
}
|
||||
|
||||
/// Create a new user block in the database.
|
||||
///
|
||||
/// # Arguments
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue